2017-03-20 4 views
1

I'm brand new to SML/NJ and I'm trying to make a recursive function that makes a listOfLists. Ex: listOf([1,2,3,4]) will output [[1],[2],[3],[4]] . I've found a recursive merge in SML/NJ, and I'm trying to use it as kind've an outline:Comment faire une liste récursive des listes SML/NJ

- fun merge(xs,nil) = xs 
= | merge(nil,ys) = ys 
= | merge(x::xs, y::ys) = 
= if (x < y) then x::merge(xs, y::ys) else y::merge(x::xs,ys); 

- fun listOf(xs) = xs 
= | listOf(x::xs) = [x]::listOf(xs); 

I'm trying to use pattern match and I'm a little confused on it. I'm pretty sure x is the head and then xs is the tail, but I could be wrong. So what I'm trying to do is use the head of the list, make it a list, and then add it to the rest of the list. But when trying to do this function, I get the error:

stdIn:15.19-15.34 Error: operator and operand don't agree [circularity] 
    operator domain: 'Z list * 'Z list list 
    operand:   'Z list * 'Z list 
    in expression: 
    (x :: nil) :: listOf xs 

This error is foreign to me because I don't have really any experience with sml/nj. How can I fix my listOf function?

Répondre

0

Vous êtes assez proche. Le problème est que dans la correspondance de modèle, un modèle comme xs (juste une variable) peut correspondre n'importe quoi. Le fait que vous le terminiez par s ne signifie pas que le motif ne peut correspondre qu'à la queue d'une liste. En utilisant s de cette façon est juste une convention de programmeur dans SML.

Ainsi, dans votre définition:

fun listOf(xs) = xs 
| listOf(x::xs) = [x]::listOf(xs); 

La première ligne indique SML revenir toutes valeurs inchangées, ce qui est manifestement pas votre intention. SML détecte que cela est incompatible avec la deuxième ligne où sont en essayant de changer une valeur après tout.

Vous devez modifier cette première ligne afin qu'elle ne corresponde pas à tout. En regardant cette fonction merge comme modèle, vous avez besoin de quelque chose qui correspond à un cas de base. Le cas de base naturel est nil (qui peut également être écrit []). Notez le rôle que nil joue dans la définition de merge. Si vous utilisez nil au lieu de xs pour le motif dans la première ligne de la définition de votre fonction, votre deuxième ligne fait exactement ce que vous voulez et la fonction fonctionnera comme prévu:

fun listOf(nil) = nil 
| listOf(x::xs) = [x]::listOf(xs); 
+0

Ah, qui fait sens. Merci pour l'aide! – XXIV

+0

Je sais que débordement de pile peut être difficile à propos de poser une autre question dans une question, mais comme c'est une question simple, j'espère que cela n'aura pas d'importance. Je dois faire une liste comme: '[[1], [2], [3], [4]]' dans [[1,2], [3,4]] '. Comment accéder à l'index suivant de la liste puisque 'x' est la première valeur et' xs' est la dernière valeur d'une liste? – XXIV

+0

Ne pensez pas du tout à utiliser des indices, utilisez plutôt la correspondance de modèles. Astuce: '[x] :: [y] :: zs' est un modèle d'une liste avec au moins deux éléments, chacun étant des listes singleton. –