Haskell无限型
我正在努力让下面的代码正常工作。这是一个有限状态机,我在其中传递一个函数作为下一个状态。使用Haskell无限型,haskell,types,Haskell,Types,我正在努力让下面的代码正常工作。这是一个有限状态机,我在其中传递一个函数作为下一个状态。使用r调用该函数,并返回结果列表+下一个函数作为下一个状态。继续调用,直到列表用完,然后返回结果的串联。monad是一个错误monad,允许我在需要时抛出错误 fsm f [] = return [] fsm f (r:rs) = do (xs, f') <- f r rest <- fsm f' rs return $ xs ++ rest 我以前见过无
r
调用该函数,并返回结果列表+下一个函数作为下一个状态。继续调用,直到列表用完,然后返回结果的串联。monad是一个错误monad,允许我在需要时抛出错误
fsm f [] = return []
fsm f (r:rs) = do
(xs, f') <- f r
rest <- fsm f' rs
return $ xs ++ rest
我以前见过无限类型错误,我知道解决它的方法是用newtype
包装一个类型。但我想不出怎么做
有人能指出你的见解吗?我想这就是你想要的:
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
。。。或者你可以把它分成两个不同的定义,如果你愿意的话
请注意,如果您不确定类型签名应该是什么,只需启用
NoMonomorphismRestriction
扩展,编译器将不会为您投诉并正确推断顶级类型。什么是f
的类型?你能写下来吗?它是f::String->m([String],t)
其中t
是f
的类型。我明白这就是为什么它是一个无限类型,但我不知道如何正确地包装它。嗨,加布里埃尔——对不起,我以为我可以继续,但我又卡住了。尝试了一个简单的f
:dup'xs=return([xs,xs],FSM dup')
。作品然后,当我尝试dup=FSM dup'
以便将其输入FSM
时,它给出了一个单态错误。我现在错过了什么?别担心!我更新了我的问题,向您展示了如何实现dup
功能。
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
dup :: (Monad m) => F m
dup = F dup' where dup' xs = return ([xs, xs], F dup')