[英]Instance of a Functor
我有以下类型newtype Arr2 e1 e2 a = Arr2 { getArr2 :: e1 -> e2 -> a }
。 我必须为它编写Functor实例,但我真的不明白我的尝试方式
instance Functor (Arr2 e1 e2) where
fmap g (Arr2 a) = Arr2 (g a)
和
instance Functor (Arr2 e1 e2) where
fmap g = g . getArr2
这实际上导致了类型
(a -> b) -> Arr2 e1 e2 a -> b
而不是期望
(a -> b) -> Arr2 e1 e2 a -> Arr2 e1 e2 b
所以,请帮助我
Functor
类具有以下定义:
class Functor f where:
fmap :: (a -> b) -> f a -> f b
(<$) :: a -> f b -> f a
(<$)
有一个默认实现: (<$) = fmap . const
(<$) = fmap . const
工作得很好。
这意味着如果我们输入一个函数( g :: a -> b
)作为第一个参数,并且一个Arr2
产生一个a
,我们必须生成一个Arr2
,如果它被应用,则在箭头的结果上调用g
。
因此,您的Arr2
的fmap
定义是:
instance Functor (Arr2 e1 e2) where
fmap g (Arr2 a) = Arr2 (\x y -> g (a x y))
或者更优雅:
instance Functor (Arr2 e1 e2) where
fmap g (Arr2 a) = Arr2 (\x -> g . (a x))
或更优雅的版本 - 由@Alec评论:
instance Functor (Arr2 e1 e2) where
fmap g (Arr2 a) = Arr2 ((g .) . a)
(你可以转换使用表达式来pointfree那些该工具 )
Willem Van Onsem提供的答案非常好,我只想建议使用一种语言扩展,可以轻松地为newtypes创建Functor
实例: DeriveFunctor
。
在模块的顶部,您可以添加:
{-# LANGUAGE DeriveFunctor #-}
然后,您可以自动派生您的Functor
实例:
newtype Arr2 e1 e2 a = Arr2 { getArr2 :: e1 -> e2 -> a } deriving Functor
以下是我如何在GHCi中找到此实例的fmap
类型:
λ > :set -XDeriveFunctor
λ > newtype Arr2 e1 e2 a = Arr2 { getArr2 :: e1 -> e2 -> a } deriving Functor
λ > :set -XTypeApplications
λ > :t fmap @(Arr2 _ _)
fmap @(Arr2 _ _) :: (a -> b) -> Arr2 t t1 a -> Arr2 t t1 b
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.