数据类型的实例应用
我正在尝试为我的数据类型编写一个 Applicative 实例
data Multinode k v = Multinode { key :: k
, values :: [v]
} deriving Show
data Multimap k v = Multimap [Multinode k v] deriving Show
我还在学习 Haskell。所以我可能会犯一些有趣的错误。如果我理解正确,Applicative 是 Functor 的一个子集。必须定义的运算符是pure和<*>。
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b
我的尝试如下
instance Applicative (Multimap k) where
pure x = Multimap [(Multinode x [x])]
(Multimap mf@((Multinode kf vsf):nsf)) <*> (Multimap mx@((Multinode kx vsx):nsx)) =
Multimap [Multinode kf (vsf <*> vsx)]
回答
地图和多地图不是自然的Applicative。原因如下:您需要
pure
:: (...) -- Possible constraint involving k, but not v
=> v -> MultiMap k v
pure
:: (...) -- Possible constraint involving k, but not v
=> v -> MultiMap k v
由于对 没有约束v,pure因此不能使用其参数生成任何键。所以结果中的键集必须始终相同,这对于<*>我所知道的任何有意义的概念都不起作用。
该semigroupoids包提供了一个名为 的类Apply,它更有前途:
这就像Applicative但没有pure. <.>类似于<*>,liftF2类似于liftA2等。该semigroupoids包包含一个实例Ord k => Apply (Map k)。您应该能够根据该类型的总体思路为您的类型考虑几个不同的实例。
- Another alternative is to include a default value that's returned when a key doesn't exist; then you could have a `pure` that sets the default and has no keys.
- Sure, meanwhile your answer talks about a somewhat different interface, an Applicative-without-pure. Sometimes one shift is appropriate, sometimes the other.