27

私はHaskellを初めて使用します。ここで問題が発生し<*>ます:

((==) <*>) :: Eq a => (a -> a) -> a -> Bool

これをどのように理解し、どのように推測できますか?

4

1 に答える 1

57

免責事項: これは慣用的な Haskell コードではありません。

最初に優先されるのは、 の「演算子セクション」です<*>。セクションと呼ばれる 1 つの引数にのみ演算子が適用されている場合。より一般的な演算子セクションの例を次に示します。

(1 +) :: Int -> Int

これは 1 に部分的に適用される関数であり、+最後の引数を 1 つ残す余地があります。それは以下と同等です:

\x -> 1 + x

したがって、コード サンプルで<*>は が に部分的に適用されて(==)いるため、次のように展開します。

((==) <*>)

= \g -> (==) <*> g

次に、 が何をしているのかを理解する必要があります<*>。これはApplicative型クラスのメンバーです:

class (Functor f) => Applicative f where
    pure  :: a -> f a
    (<*>) :: f (a -> b) -> f a -> f b

これは、<*>を実装する任意の型で機能するようにオーバーロードされていることを意味しますApplicativeApplicativeタイプの 1 つのインスタンスは次の((->) r)とおりです。

instance Applicative ((->) r) where
    pure  :: a -> ((->) r) a
    (<*>) :: (->) r (a -> b) -> (->) r a -> (->) r b

プレフィックス形式で使用されている意味を囲む括弧(->)(これは、このようなクラス インスタンスを定義するときに構文上の理由で必要です)。それを中置形式に展開すると、次のようになります。

instance Applicative ((->) r) where
    pure  :: a -> r -> a
    (<*>) :: (r -> a -> b) -> (r -> a) -> (r -> b)

あなたの特定の例では、の最初の引数は<*>(==)の型を持つ演算子です。

(==) :: Eq e => e -> e -> Bool

したがって、これをコンパイラに渡すと、 、、およびのシグネチャ(<*>)の型について、次のように推測できます。rab(<*>)

 (<*>) ::        (r -> a -> b   ) -> (r -> a) -> (r -> b)
 (==)  :: Eq e => e -> e -> Bool
                  |    |    |
                  |    |    +-> `b` must be `Bool`
                  |    |
                  |    +------> `a` must be `e`
                  |
                  +-----------> `r` must also be `e`

したがって(==)、 の最初の引数として指定すると、次の(<*>)推論された型が得られます。

((==) <*>) :: Eq e => (e -> e) -> (e -> Bool)

(->)は右結合であるため、右括弧を省略し、 に変更eaて、取得した最終的な署名を与えることができます。

((==) <*>) :: Eq a => (a -> a) -> a -> Bool

しかし、これは実際に何をしているのでしょうか?のインスタンス(<*>)に対して がどのように定義されているかを確認する必要があることを理解するには、次のようにします。Applicative((->) r)

(f <*> g) r = f r (g r)

と置き換えるfと、次の(==)ようになります。

((==) <*> g) r = (==) r (g r)

(==)括弧で囲む場合、それは接頭表記で使用していることを意味します。これは、括弧を削除して中置記法に戻すと、次のようになることを意味します。

((==) <*> g) r = r == (g r)

これは次と同等です。

((==) <*>) = \g r -> r == g r

つまり、関数は と の 2 つのパラメーターを取りgrif requalsを確認しg rます。

于 2013-09-15T15:10:37.713 に答える