仍然没有百分百地了解如何制作更复杂类型的实例。有这个:
data CouldBe a = Is a | Lost deriving (Show, Ord)
以Functor
为例,制作了Maybe
的实例:
instance Functor CouldBe where
fmap f (Is x) = Is (f x)
fmap f Lost = Lost
用于执行以下操作:
tupleCouldBe :: CouldBe a -> CouldBe b -> CouldBe (a,b)
tupleCouldBe x y = (,) <$> x <*> y
CouldBe
必须是Applicative
的实例,但是您将如何处理呢?当然可以查找并复制它,但是我想学习其背后的过程,最后以instance
声明CouldBe结尾。
答案 0 :(得分:3)
您只需按照以下类型将其写出即可:
instance Applicative CouldBe where
{-
Minimal complete definition:
pure, ((<*>) | liftA2)
pure :: a -> f a
pure :: a -> CouldBe a
liftA2 :: (a -> b -> c) -> f a -> f b -> f c
liftA2 :: (a -> b -> c) -> CouldBe a -> CouldBe b -> CouldBe c
-}
pure a = fa
where
fa = ....
liftA2 abc fa fb = fc
where
fc = ....
根据
data CouldBe a = Is a | Lost
我们的工具集是
Is :: a -> CouldBe a
Lost :: CouldBe a
但是我们也可以使用模式匹配,例如
couldBe is lost (Is a) = is a
couldBe is lost (Lost) = lost
couldBe :: ? -> ? -> CouldBe a -> b
couldBe :: ? -> b -> CouldBe a -> b
couldBe :: (a -> b) -> b -> CouldBe a -> b
所以
-- pure :: a -> f a
pure :: a -> CouldBe a
与
匹配 Is :: a -> CouldBe a
所以我们定义
pure a = Is a
然后,对于liftA2
,我们遵循以下数据案例:
-- liftA2 :: (a -> b -> c) -> f a -> f b -> f c
-- liftA2 :: (a -> b -> c) -> CouldBe a -> CouldBe b -> CouldBe c
liftA2 abc Lost _ = ...
liftA2 abc _ Lost = ...
liftA2 abc (Is a) (Is b) = fc
where
c = abc a b
fc = .... -- create an `f c` from `c`:
-- do we have a `c -> CouldBe c` ?
-- do we have an `a -> CouldBe a` ? (it's the same type)
但是在前两种情况下,我们没有a
或b
;因此我们必须一无所有提出CouldBe c
。我们的
完成所有遗漏的部分后,我们可以将表达式直接替换为定义,从而消除所有不需要的临时值/变量。