Mig*_*uel 16 haskell type-constructor
我目前在第8章的学习,你一个Haskell,和我已经达成了部分Functor类型类.在上述部分中,作者给出了如何使不同类型成为类的实例(例如Maybe,自定义Tree类型等)的示例.看到这一点,我决定(为了乐趣和实践)尝试为该Data.Set类型实现实例; Data.Set.map当然,在所有这些忽视中.
实际的实例本身很简单,我把它写成:
instance Functor Set.Set where
fmap f empty = Set.empty
fmap f s = Set.fromList $ map f (Set.elems s)
Run Code Online (Sandbox Code Playgroud)
但是,因为我碰巧使用的功能fromList,它可以提供一个类约束呼吁在使用的类型Set是Ord,因为是由编译器错误解释:
Error occurred
ERROR line 4 - Cannot justify constraints in instance member binding
*** Expression : fmap
*** Type : Functor Set => (a -> b) -> Set a -> Set b
*** Given context : Functor Set
*** Constraints : Ord b
Run Code Online (Sandbox Code Playgroud)
请参阅:实例
我尝试在实例上添加约束,或者添加类型签名fmap,但都没有成功(两者都是编译器错误.)
鉴于这种情况,如何实现约束并满足约束?有什么办法吗?
提前致谢!:)
Tik*_*vis 15
不幸的是,使用标准类没有简单的方法Functor.这就是为什么Set不拿出一个Functor默认实例:你不能写一个.
这是一个问题,并且有一些建议的解决方案(例如Functor以不同的方式定义类),但我不知道是否就如何最好地处理这个问题达成共识.
我相信一种方法是Functor使用约束种类重写类来重新定义新Functor类可能具有的附加约束实例.这将允许您指定Set必须包含类中的Ord类型.
另一种方法仅使用多参数类.我只能在Monad课堂上找到关于这样做的文章,但是让Set部分Monad面孔成为同样的问题Functor.它被称为受限制的Monads.
在这里使用多参数类的基本要点似乎是这样的:
class Functor' f a b where
fmap' :: (a -> b) -> f a -> f b
instance (Ord a, Ord b) => Functor' Data.Set.Set a b where
fmap' = Data.Set.map
Run Code Online (Sandbox Code Playgroud)
从本质上讲,你在这里所做的是使该类型中的Set类的也有一部分.然后,这可以让您在编写该类的实例时约束这些类型的内容.
这个版本Functor需要两个扩展:MultiParamTypeClasses和FlexibleInstances.(您需要第一个扩展才能定义类,第二个扩展能够为其定义实例Set.)
Haskell:一个Foldable的例子,它不是Functor(或者不是Traversable)?对此有一个很好的讨论.