我有以下类型newtype Arr2 e1 e2 a = Arr2 { getArr2 :: e1 -> e2 -> a }。我必须为它编写 Functor 实例,但我真的不明白我是如何尝试的
instance Functor (Arr2 e1 e2) where
fmap g (Arr2 a) = Arr2 (g a)
Run Code Online (Sandbox Code Playgroud)
和
instance Functor (Arr2 e1 e2) where
fmap g = g . getArr2
Run Code Online (Sandbox Code Playgroud)
这实际上导致类型
(a -> b) -> Arr2 e1 e2 a -> b
Run Code Online (Sandbox Code Playgroud)
而不是想要
(a -> b) -> Arr2 e1 e2 a -> Arr2 e1 e2 b
Run Code Online (Sandbox Code Playgroud)
所以请帮帮我
该Functor班有作为的定义:
class Functor f where:
fmap :: (a -> b) -> f a -> f b
(<$) :: a -> f b -> f a
Run Code Online (Sandbox Code Playgroud)
该(<$)有一个默认的实现:(<$) = fmap . const它工作正常。
所以这意味着,如果我们输入一个函数 ( g :: a -> b) 作为第一个参数,并且一个Arr2产生 an a,我们必须生成一个Arr2,如果它被应用,我们必须在箭头g的结果上调用它。
因此fmap,您的定义Arr2是:
instance Functor (Arr2 e1 e2) where
fmap g (Arr2 a) = Arr2 (\x y -> g (a x y))Run Code Online (Sandbox Code Playgroud)
或者更优雅:
instance Functor (Arr2 e1 e2) where
fmap g (Arr2 a) = Arr2 (\x -> g . (a x))Run Code Online (Sandbox Code Playgroud)
或者更优雅的版本- @Alec评论:
instance Functor (Arr2 e1 e2) where
fmap g (Arr2 a) = Arr2 ((g .) . a)Run Code Online (Sandbox Code Playgroud)
(你可以转换表达式pointfree使用那些该工具)