我正在通过these Haskell'中间'练习,我做了以下几个实例:
class Fluffy f where
furry :: (a -> b) -> f a -> f b
instance Fluffy [] where
furry f [] = []
instance Fluffy Maybe where
furry f (Just e) = Just (f e)
furry f (Nothing) = Nothing
然而,第三个问题语法让我感到难过:
instance Fluffy ((->) t) where
...
我已经阅读了箭头操作符并阅读了this的答案,该答案解释了(->)
在Monad实例中的作用。但是,我不太了解(->)
在Functors的上下文中是如何工作的?
答案 0 :(得分:9)
我们有:
class Fluffy f where
furry :: (a -> b) -> f a -> f b
我们要定义:
instance Fluffy ((->) t) where
furry = ...
这意味着在上面的实例中,furry
应该具有(a -> b) -> f a -> f b
类型f
((->) t)
,或者换句话说:
furry :: (a -> b) -> ((->) t) a -> ((->) t) b
正如((+) 2) 3
与2 + 3
相同,((->) X) Y
与X -> Y
相同(它是咖喱运算符应用程序,甚至可以在类型级别工作):< / p>
furry :: (a -> b) -> (t -> a) -> (t -> b)
我们可以将上述签名读作“从a
到b
的函数以及从t
到a
的函数,从{返回函数{1}}至t
“。
现在你必须实现它。 : - )
答案 1 :(得分:2)
我们将Functor
实例定义为:
instance Functor ((->) a) where
fmap f g = \a -> f (g a)
-- Pointfree definition: fmap = (.)
也就是说,(->)
仿函数可以与只能通过获取类型a
的某个值并使用它打开容器“打开”的容器相媲美。然后,任何fmap
只是在我们“打开”容器后更改值。即:编写功能。
这有点像Maybe
仿函数,因为我可以将函数应用于值(如果它存在),但对于(->)
仿函数我在做之前就知道它是什么。
但请记住,所有monad都是仿函数,因为我们可以这样定义fmap
:
fmap f m = m >>= (\a -> return (f a))
因此,如果您了解Monad
实例中的内容,则应明确其在Functor
实例中的作用。