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)?对此有一个很好的讨论.