【问题标题】:Haskell Infinite TypeHaskell 无限类型
【发布时间】:2013-03-19 08:44:45
【问题描述】:

我正在尝试使下面的代码正常工作。这是一个有限状态机,我在其中传递一个函数作为下一个状态。该函数使用r 调用并返回结果列表+ 下一个函数作为下一个状态。继续调用直到列表用完,并返回结果的串联。 monad 是一个错误 monad,允许我在需要时抛出错误。

fsm f []     = return []
fsm f (r:rs) = do
    (xs, f') <- f r
    rest     <- fsm f' rs
    return $ xs ++ rest

错误是:

Occurs check: cannot construct the infinite type: t1 = t0 -> m0 ([a0], t1)
In the first argument of `fsm', namely f'

我以前见过无限类型错误,我理解解决它的方法是用newtype 包装一个类型。但我无法弄清楚如何完成这项工作。

有人可以指出其中的见解吗?

【问题讨论】:

  • f 的类型是什么?你能写下来吗?
  • 它将是 f :: String -&gt; m ([String], t),其中 t 将是 f 的类型。我明白这就是为什么它是无限类型但无法弄清楚如何正确包装它的原因。

标签: haskell types


【解决方案1】:

我想这就是你想要的:

newtype F m = F { unF :: String -> m ([String], F m) }

fsm :: (Monad m) => F m -> [String] -> m [String]
fsm f []     = return []
fsm f (r:rs) = do
    (xs, f') <- unF f r
    rest     <- fsm f' rs
    return $ xs ++ rest

您是对的,您需要在任何时候使用递归类型时都需要使用 datanewtype

在回复您的评论时,您将如何实现 dup 函数:

dup :: (Monad m) => F m
dup = F dup' where dup' xs = return ([xs, xs], F dup')

...如果您愿意,也可以将其拆分为两个单独的定义。

请注意,如果您不确定类型签名应该是什么,只需启用 NoMonomorphismRestriction 扩展名,编译器就不会抱怨并为您正确推断顶级类型。

【讨论】:

  • 嗨 Gabriel -- 抱歉,我以为我可以继续,但我又卡住了。尝试了一个简单的f:dup' xs = return ([xs, xs], FSM dup')。作品。然后当我尝试dup = FSM dup' 以便将其输入fsm 时,它给了我一个单态错误。我现在错过了什么?
  • 别担心!我更新了我的问题,向您展示了如何实现您的 dup 函数。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-22
  • 1970-01-01
  • 1970-01-01
  • 2012-03-22
  • 2012-10-22
相关资源
最近更新 更多