J'essayais de mettre en œuvre une machine d'état dans Haskell. Une version simplifiée est la suivante:Modèle de machine d'état dans Haskell: erreur de type infinie
Dans n'importe quel état, vous pouvez alimenter la machine en entier et vous obtenez un nombre entier. Dans l'état A, la machine double ses entrées. Dans l'état B, la machine vous restitue simplement votre entrée. Chaque fois que vous voyez un zéro dans l'un ou l'autre état, passez à l'autre état. Sinon, l'état ne change pas.
Voici la méthode mon: il suffit que chaque état soit une fonction qui renvoie à la fois sa sortie et la fonction correspondant à l'autre état.
module Main where
a x | x == 0 = (0,b)
a x = (2*x, a)
b x | x == 0 = (0,a)
b x = (x, b)
evalstate s [] = []
evalstate s (x:xs) = (v:evalstate s' xs)
where (v,s') = s x
main :: IO()
main = putStrLn $ show $ evalstate a [1,1,2,3,4,0,2,3,3]
Malheureusement, les types de a
et b
sont infinies et se plaint GHC:
Occurs check: cannot construct the infinite type: t = t1 -> (t2, t)
Quelle est la façon d'exprimer ce modèle dans Haskell?
je pourrais bien sûr faire quelque chose comme:
s 'a' x | x == 0 = (0,'b')
en utilisant des codes de caractères pour l'état, mais le modèle de fonction semble plus élégante.
tâche pour la lecteur: Rendez ce modèle plus commun et créez une interface monadique pour celui-ci. – fuz
Sur un point de style: il est généralement plus clair si vous dites 'a 0 = (0, b)' au lieu de 'a x | x == 0 = (0, b) '. – dave4420
Au lieu d'un code de caractère, je suggère d'utiliser un type de données, comme 'data State = A | B'. mais le premier est sympa aussi. – fuz