制作应用实例

问题描述 投票:5回答:1

仍然不是百分之百地避免如何制作更复杂类型的实例。拥有这个:

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的一个例子,但是你会怎么做呢?当然,我可以查找并复制它,但我想了解它背后的过程,最后得到了canze的instance声明。

haskell typeclass applicative
1个回答
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)

但在前两种情况下,我们没有ab;所以我们必须从无到有地提出一个CouldBe c。我们的工具集中也有这个工具。

完成所有缺失的部分后,我们可以直接将表达式替换为定义,从而消除所有不需要的临时值/变量。

© www.soinside.com 2019 - 2024. All rights reserved.