Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell无限类型与my FSM函数_Haskell_Types - Fatal编程技术网

Haskell无限类型与my FSM函数

Haskell无限类型与my FSM函数,haskell,types,Haskell,Types,当我试图编写有限状态机时,我在Haskell中遇到了“无限类型”。我认为以下是非常直观的: fsm [] _ acc = Right acc fsm (x:xs) state acc = case state acc x of Left err -> Left err Right (s, a) -> fsm xs s a 我给状态函数当前状态(累加器)和新事件,状态函数生成下一个状态函数和新累加器。我重复,直到我没有更

当我试图编写有限状态机时,我在Haskell中遇到了“无限类型”。我认为以下是非常直观的:

fsm []     _     acc = Right acc
fsm (x:xs) state acc =
    case state acc x of
        Left err     -> Left err
        Right (s, a) -> fsm xs s a
我给状态函数当前状态(累加器)和新事件,状态函数生成下一个状态函数和新累加器。我重复,直到我没有更多的事件

编译器告诉我:

Occurs check: cannot construct the infinite type:
  t1 = b0 -> t0 -> Either a0 (t1, b0)
In the second argument of `fsm', namely `s'

因为
state
现在是一个无限类型。如何重新安排它以使其工作?

像这样的无限类型会对类型系统造成严重破坏;它们不会使它变得不安全,但它们会导致大量程序键入您并不真正想要的类型,从而隐藏错误,我相信它们也会使类型推断更加困难

谢天谢地,解决方案很简单:您只需要制作一个
newtype
包装器<代码>数据和
新类型
声明当然可以是递归的(否则,我们甚至不能定义列表!);它只是简单的、未包装的类型,而不是

newtype FSMState err acc ev =
    FSMState { stepFSM :: acc -> ev -> Either err (FSMState err acc ev, acc) }

fsm :: [ev] -> FSMState err acc ev -> acc -> Either err acc
fsm []     _     acc = Right acc
fsm (x:xs) state acc =
    case stepFSM state acc x of
        Left err     -> Left err
        Right (s, a) -> fsm xs s a

谢谢对我来说,这只是给无限类型一个名称,但类型本身仍然是自引用的。编译器本身甚至以同样的方式命名无限类型。我本以为编译器可以通过给它起个名字来自动化它。我弄错了吗?@Ana:哈斯凯尔确实认为你的程序无效是出于选择,而不是出于必要,这是有很好的理由的;我现在没有任何链接,但是我们依赖类型系统来检查的许多常见错误——比如缺少一个参数或写两次函数名——如果允许无限类型,就会变成有效类型(但已损坏)的程序。请注意,这并不像给类型命名那么简单:
type infinite=(Bool,infinite)
也被禁止;您必须将其包装成一个数据类型,这样可以避免所有可能的错误,因为您必须显式地对其进行构造和模式匹配(或使用访问器函数)。