我在Haskell Book(第16章Functor)的练习中挣扎。鉴于以下内容,我希望我定义fmap
:
{-# LANGUAGE FlexibleInstances #-}
newtype Flip f a b =
Flip (f b a)
deriving (Eq, Show)
newtype K a b =
K a
instance Functor (Flip K a) where
fmap = undefined
在之前的练习中,我已经完成了以下工作:
data K a b =
K a
instance Functor (K a) where
fmap f (K x) = K x
但对于Flip a b
,我甚至无法理解如何开始使用,例如如何继续fmap f Flip ...
。
我想在做之前我也应该为newtype K a b
编写一个仿函数,类似于我所做的data K a b
:
instance Functor (K a) where
fmap f (K x) = K x
但我无法理解如何继续Flip f a b
的Functor实例。
任何想法,提示?
答案 0 :(得分:1)
让我们来看看你的解决方案:
instance Functor (Flip K a) where
fmap f (Flip (K a)) = Flip (K (f b))
Flip (K a)
实际意味着什么?
K
是常量仿函数,您可以正确实现。它忽略函数f
并始终返回K a
。但幕后实际发生的是值K a b
转换为K a c
。即使忽略了函数f
,第二种类型的K
也会根据f
的类型进行更改。
现在,如果我们Flip
K
,我们只需转变参数:
Flip (K a b) == K b a
我们不是有一个常数值而忽略了这个函数,而是有一个变化的值和一个常数"忽略"类型。通过显式类型签名查看实现,我们得到:
instance Functor (Flip K a) where
fmap :: (b -> c) -> Flip K a b -> Flip K a c -- or:
fmap :: (b -> c) -> K b a -> K c a
fmap f (Flip (K a)) = Flip (K (f b))
正如您已经总结的那样,唯一可能的实现是上面的那个。
您可以在this问题中查看Constant
仿函数的用例。