70110


[箱で考えるFunctor、ApplicativeそしてMonad -
Qiita](https://qiita.com/suin/items/0255f0637921dcdfe83b)
に載っているサンプルのコード（下記引用）の挙動がすこし不思議だなと思ったので、実際の処理は、実装を読めばわかるだろうと考えました。

>
[code]

>     > [(*2), (+3)] <*> [1, 2, 3]
>     [2, 4, 6, 4, 5, 6]
>  
[/code]

そこで

<https://hackage.haskell.org/package/base-4.14.0.0/docs/src/GHC.Base.html#%3C%2A%3E>
を見てみると

>
[code]

>     (<*>) :: f (a -> b) -> f a -> f b
>     (<*>) = liftA2 id
>  
[/code]

となっており、じゃあ次は `leftA2` を見ないといけないんだなと考えみにいってみると、

>
[code]

>     liftA2 :: (a -> b -> c) -> f a -> f b -> f c
>     liftA2 f x = (<*>) (fmap f x)
>  
[/code]

となって、また `<*>` が出てきてしまいました。

再帰ぽいような動きなんでしょうか？ これ以上どう読んだらいいのかわからなくなってしまいました。

`(<*>) (fmap f x)` はどのように解釈すればいいんでしょうか？


CC BY-SA 4.0
2020-09-03T12:45:04.817
70109
2020-09-04T10:53:16.863
2020-09-04T10:53:16.863
2901
9008
question
haskell
Applicative [] の <*> の実装はどのようにして読む（解釈する）のでしょうか？


読んでおられたところは，前後の文脈を含めるとここです

[code]

    class Functor f => Applicative f where
        {-# MINIMAL pure, ((<*>) | liftA2) #-}
        -- | Lift a value.
        pure :: a -> f a
        -- | Sequential application.
        (<*>) :: f (a -> b) -> f a -> f b
        (<*>) = liftA2 id
        -- | Lift a binary function to actions.
        liftA2 :: (a -> b -> c) -> f a -> f b -> f c
        liftA2 f x = (<*>) (fmap f x)
    
[/code]

つまり，ここは（インスタンスに関係なく） `Applicative` の定義を作っているところ（「`Applicative`
っていうのはこういうもの」）で，`(<*>) = liftA2 id` などはそのデフォルト実装を与えるものです．おっしゃるとおり `<*>`と
`liftA2` の定義は循環しています．これは無意味なことではなくて，あとから何かの型（たとえばリスト）を Applicative
にするときに，どちらかだけ定義すれば良いようになっています（たとえば， `<*>` の定義だけ具体的に書き下せば，`liftA2` の定義は `<*>
(fmap f x)` で決まる）．

具体的な定義は，同じページのもう少し下，こういうところにあります

[code]

    instance Applicative [] where
        {-# INLINE pure #-}
        pure x    = [x]
        {-# INLINE (<*>) #-}
        fs <*> xs = [f x | f <- fs, x <- xs]
        {-# INLINE liftA2 #-}
        liftA2 f xs ys = [f x y | x <- xs, y <- ys]
        {-# INLINE (*>) #-}
        xs *> ys  = [y | _ <- xs, y <- ys]
    
[/code]

[リスト内包表記](https://wiki.haskell.org/List_comprehension)
が使われていて一瞬面食らうかもしれませんが，少なくとも定義の循環はないのが見て取れると思います．


CC BY-SA 4.0
2020-09-03T13:40:20.823
70110
2020-09-03T13:52:34.953
2020-09-03T13:52:34.953
2901
2901
70109
answer