在Simple Haskell函数中不断获取(使用FlexibleContexts允许此)错误
我只是在和Haskell monads玩,我不断地遇到一个我似乎无法修复的错误。我的代码段使用状态Monad将字符串中的前两个字符相加,并作为状态的一部分返回。我的“put”行一直给我错误信息:在Simple Haskell函数中不断获取(使用FlexibleContexts允许此)错误,haskell,monads,state-monad,Haskell,Monads,State Monad,我只是在和Haskell monads玩,我不断地遇到一个我似乎无法修复的错误。我的代码段使用状态Monad将字符串中的前两个字符相加,并作为状态的一部分返回。我的“put”行一直给我错误信息: * Non type-variable argument in the constraint: MonadState [a] m (Use FlexibleContexts to permit this) * When checking the inferred type testH ::
* Non type-variable argument in the constraint: MonadState [a] m
(Use FlexibleContexts to permit this)
* When checking the inferred type
testH :: forall (m :: * -> *) a. MonadState [a] m => [a] -> m [a]
我怎样才能解决这个问题?扩展语言不是一个选项,我只需要知道如何更改代码以使其正常工作
test xs =
runState (testH (tail xs)) ((head xs):[])
testH xs =
do
a <- get
put ((head xs):a)
b <- get
return b
testxs=
运行状态(testH(尾部xs))((头部xs):[])
testH-xs=
做
a您可以按照建议启用FlexibleContexts
,或者通过更改函数来处理比列表更一般的内容来解决此问题
问题是Haskell不允许在上下文中使用非类型变量。如果你写出了你的函数类型(你无论如何都应该这么做),你会得到
这意味着它是一个函数,它接受一个值列表并返回某个monad中的操作,该monad能够保持与输入类型相同的值列表的状态。不幸的是,上下文中的[a]
位无效,因为它有一个非类型变量(即列表类型构造函数)
这里最好的解决方案是启用扩展,它允许在上下文中使用非类型变量。这并不危险,只是放松了标准。事实上,多参数类型类(例如MonadState
)不是有效的Haskell,因此不管您是否喜欢,您已经在使用语言扩展了
如果这真的不是一个选项,您可以将其更改为(Monad m,SomeTypeclass f,MonadState(fa)m)
,并重写您的函数以使用您选择的SomeTypeclass
后面的任何构造函数。这将从类型中删除列表类型构造函数,并允许代码在不使用FlexibleContexts
的情况下工作。是否导入控件.Monad.State
?如果是这样,请尝试导入Control.Monad.Trans.State
。我不完全确定我是否知道您所说的“扩展语言不是一个选项”是什么意思。如果您只是在玩monad,为什么不在代码的顶部添加{-#LANGUAGE FlexibleContexts#-}
“扩展语言不是一个选项”,除非您只是通过在范围中使用MonadState
来使用多ramtypeclass
,因此已经扩展了语言。
testH :: (Monad m,MonadState [a] m) => [a] -> m [a]