2013-02-19 4 views
0

En sml/nj, je veux créer une fonction qui prend une liste de listes non vides, et retourne une liste des premiers éléments de chacune de ces listes non vides.Comment modéliser des listes imbriquées?

fun get_first [] = [] 
| get_first x::xs = (hd x)::get_first xs; 
get_first: ('a list) list -> 'a list; 

Cependant cela ne fonctionne pas ... ce que quelqu'un sait ce qui est erroné?

Répondre

1

Vous avez oublié de mettre entre parenthèses autour de votre modèle de liste x::xs, comme ceci:

fun get_first [] = [] 
    | get_first (x::xs) = (hd x)::get_first xs 

La raison pour laquelle il ne fonctionne pas est un peu « compliqué ». En SML, les listes sont simplement définies comme un type de données et du sucre syntaxique. Il ressemble fondamentalement quelque chose comme ça

datatype 'a list = nil | :: of ('a * 'a list) 

Comme il est possible de correspondance de motif sur les constructeurs de type de données, il est possible de correspondance de motif contre les deux nil (ce que vous écrivez normalement []) et ::.
Toutefois, si vous ne placez pas de parenthèses autour de lui, il sera interprété comme si la fonction correspondait à 3 arguments au cari. Ceci est peut-être mieux visualisé comme celui-ci

| get_first (x) (::) (xs) = .... 

également Prenez note que vous pouvez facilement mettre en œuvre, en utilisant la fonction de carte

fun get_first xs = map hd xs 
+0

Pour être pédant, puisque '' :: '' est donné le statut infixe dans la lib standard, la 2ème clause du code original est réellement analysée comme '' (get_first x) :: xs = ... '', qui à son tour est sucre pour '' op :: (get_first x, xs) =. ..''. En d'autres termes, il essaie de définir une fonction nommée '' :: ''. –

+0

@Andreas: Ce serait vrai si c'était dans le corps de la fonction, mais comme il fait partie d'une clause de fonction, il est analysé différemment, comme vu par l'un des messages d'erreur: get_first = (fn nil => nil | , _, xs) => hd :: get_first ). Ici, on voit que la deuxième clause est analysée dans le modèle qui correspond à un triplé. Ainsi, il est analysé comme 3 arguments au curry en premier lieu. –

+0

Shrug. Strictement parlant, il s'agit simplement d'une erreur de syntaxe, car une clause de fonction infix n'autorise que des motifs atomiques (pour une raison quelconque). Je ne sais pas pourquoi SML/NJ (ce que je suppose est ce que vous avez essayé) ne tente même pas de taper-vérifier à ce point. De toute façon, je ne vois pas comment son interprétation a un sens. –