【发布时间】:2019-03-15 22:12:14
【问题描述】:
我在为自定义数据类型(我无法更改)编写自己的仿函数实例时遇到问题。数据类型定义为:
data Foo a = Baz String (Qux -> Foo a) | Bar a
data Qux = None | Quux String
我的问题是为Foo 类型编写函子。具体来说,我不确定如何正确地将我的仿函数函数f 应用于Foo 中的函数。我正在考虑以某种方式在构造函数中调用该函数,但由于我没有可用的Qux,所以我被卡住了。
instance Functor Foo where
fmap f (Bar a) = Bar (f a)
fmap f (Baz s ???) = Baz s (???) -- What goes here?
-- Clearly, something like this doesn't work
-- fmap f (Baz s g) = Baz s (f g)
-- I've also tried something like this, but I'm not sure where to go from there
-- fmap f (Baz s (None -> Bar b)) = Baz s (f b) ???
-- fmap f (Baz s (Quux x -> Bar b)) = Baz s ???
【问题讨论】:
-
第一部分很简单:
Baz是两种类型的乘积,所以你只需要在Baz s g(其中g :: Qux -> Foo a)上进行模式匹配。用g做什么 是棘手的部分 :) -
在 Haskell 中,思考这个问题的方法就是“遵循类型”。你有一个函数
f :: a -> b,一个Qux -> Foo a类型的函数(我称之为g),你想要一个Qux -> Foo b类型的函数。我很确定只有一种方法可以用你在这里得到的东西来做到这一点 - 并且看到它,不要害怕使用递归;)