-1

関数の定義は次のとおりです。

fmap :: (a -> b) -> f a -> f b

あなたはそれが何を意味するのか正確に説明できますか?私が理解できないのはf af bなぜこのように書くことができるのですか?つまり、なぜ構文的に正しく、うまくコンパイルできるのでしょうか?

(a -> b) -> a -> b変数は1つ(a -> b) -> f -> fだけにする必要があると思います(a -> b) -> c -> d

繰り返しますが、問題は関数の意味ではなく、構文が正しいかどうかです。

4

3 に答える 3

7

「通常の」map関数の署名を受け入れmap :: (a -> b) -> [a] -> [b]ますか?

ここで、代わりに( と比較して)[a]を書いたので、署名がと表示されたふりをします。この署名は.List aMaybe amap :: (a -> b) -> List a -> List b(a -> b) -> f a -> f bf = List

関数fmap :: (a -> b) -> f a -> f bは、 のmapような他の型コンストラクターへの一般化ですMaybe

于 2013-07-28T06:44:09.593 に答える
4

Haskell[1] 型シグネチャは 3 つの要素で構成されています

  • タイプ変数。
    • それらは暗黙のうちに普遍的に量化されています。構文的には、小文字で始まります。
  • 具体的なタイプ。
    • それらは、型変数を埋める実際の「もの」です。大文字で始まります。
  • 関数矢印。
    • これは、機能を表しています。それはカレーで何とか何とか何とかです。構文的には矢印です。

あなたの例では、2つの要素があります。ab、およびfは型変数であり、関数矢印があります。

aつまり、具象型によってそのままインスタンス化できますb。一方、[2] の種類があります。つまり、 と と同じ方法でインスタンス化することはできません。種類の型を取り、具体的な型を生成する型でインスタンス化する必要があります。*f* -> *fab*

たとえば、その型の値を構築する前にMaybe、別の型、たとえば を指定する必要があります。Intたとえば、しかし意味Just 1 :: Maybe Intwat :: Maybeありません。したがって、適用は、型を除いて、 value-function をf avalue に適用するのと同じです。部分適用もあります!fa

したがって、「あるタイプを取り、それをあるタイプに適用し、あるタイプに適用されたタイプの値を返すf a -> f b関数」と読みます。fafb

[1] Haskell とは、バニラ Haskell のことです。型演算子、ランク N 型などは物事を複雑にします。

[2] これは通常の機能ではありません->。値ではなく型について話しています。

于 2013-07-28T04:09:01.390 に答える
2

Type1 Type2Haskellの構文は、型の適用を意味します。たとえば、 type を見たことがあるかもしれませんMaybe IntegerMaybeは次のように定義されているため、機能します。

data Maybe a = ...

type variable に注意してくださいaMaybeこれは、型自体として使用する前に、何らかの型に適用する必要があることを意味します。ではMaybe Integer、 にa設定されていIntegerます。

問題ではf a、つまり、型変数が別の型変数に適用されます。これは、それがもう 1 つの型に適用されることを期待するfようなものである可能性があり、それ自体が型であるようなものである可能性があることを意味します。MaybeaInteger

于 2013-07-28T13:05:29.567 に答える