我想用RMonad
. 有没有使用“as monad”功能的方法
- 有一个身份 rmonad,将 monad 转换器应用于?
StateT
有变压器之类的常用东西吗?- 向现有的 monad 添加约束?(例如,如果一个人想要一个
StateT
带有额外约束的)
不幸的是,我还没有掌握使其工作的数据系列等东西......否则我可能会很乐意自己编写代码。
编辑
我从图书馆资源中一起破解StateT
,看看它是否有效......
我想用RMonad
. 有没有使用“as monad”功能的方法
StateT
有变压器之类的常用东西吗?StateT
带有额外约束的)不幸的是,我还没有掌握使其工作的数据系列等东西......否则我可能会很乐意自己编写代码。
我从图书馆资源中一起破解StateT
,看看它是否有效......
快速浏览后,您的 StateT 版本看起来是正确的。不幸的是,使用 RMonad 等。人。确实需要复制几乎所有内容;我开始使用适合编写一些代码并放弃了,因为它涉及太多重复(最后我真的不需要它)。
编辑:
根据我对Suitable
工作原理的记忆,它是这样的:
考虑Functor
类:Set
不能是它的实例,因为它需要额外的Ord
约束。
一个天真的方法是这样的:
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE MultiParamTypeClasses #-}
import qualified Data.Set as S
class MyFunctor c a | c -> a where
myfmap :: (MyFunctor c b) => (a -> b) -> c a -> c b
instance (Ord a) => MyFunctor S.Set a where
myfmap = S.map
但这会返回以下错误:
Error: test.hs:11:16: Could not deduce (Ord b) arising from a use of `S.map'
from the context (Ord a)
bound by the instance declaration at /tmp/test.hs:10:10-37
or from (MyFunctor S.Set b)
bound by the type signature for
myfmap :: MyFunctor S.Set b => (a -> b) -> S.Set a -> S.Set b
at /tmp/test.hs:11:7-20
Possible fix:
add (Ord b) to the context of
the type signature for
myfmap :: MyFunctor S.Set b => (a -> b) -> S.Set a -> S.Set b
or the instance declaration
In the expression: S.map
In an equation for `myfmap': myfmap = S.map
In the instance declaration for `MyFunctor S.Set a'
为什么是这样?这是因为在实例级别没有保留或找到约束,所以GHC没有意识到在使用时myfmap
,应该有一个Ord
约束b
。
该Suitable
类型用于显式创建一个约束字典,允许您指定这些类型的约束:
import Data.Suitable
import qualified Data.Set as S
class MyFunctor c where
myfmap :: (Suitable c a, Suitable c b) => (a -> b) -> c a -> c b
instance MyFunctor S.Set where
myfmap f s = withConstraintsOf s
$ \ SetConstraints
-> withResConstraints $ \ SetConstraints -> S.map f s
(其中SetConstraints
已在 中定义Data.Suitable
)
这个实现有效,但它确实使类型签名更加复杂,并且方法实现有点复杂(注意这里我们需要引入SetConstraints
两次:一次用于Set a
,另一个用于Set b
)。请注意,对于没有任何约束的类型,不需要任何Suitable
约束函数。
我已经开始尝试Suitable
在 Typeclassopedia 中创建类的版本,但因为实例变得相当多毛而放弃了。