私はHaskellに不慣れであり、一般に関数型プログラミングに不慣れであり、その構文には少し不快です。
次のコードでは、=>
は何を示していますか?また、(Num a, Ord a)
?
loop :: (Num a, Ord a) => a -> (t -> t) -> t -> t
これは型クラスの制約です。 (Num a, Ord a) => ...
は、loop
がa
およびNum
タイプクラスのインスタンスである任意のタイプOrd
で機能し、それぞれ数値タイプおよび順序付きタイプに対応することを意味します。基本的に、loop
は=>
の右側にタイプがあると考えることができますが、a
はNum
とOrd
のインスタンスである必要があります。
タイプクラスは基本的にOOPインターフェイスに似ていると考えることができます(ただし、同じものではありません!)—インスタンスがサポートする必要のある一連の定義をカプセル化し、ジェネリックコードを記述できます。これらの定義を使用します。たとえば、Num
には加算や乗算などの数値演算が含まれ、Ord
にはより小さい、より大きいなどが含まれます。
型クラスの詳細については、 この紹介 from Learn You a Haskell を参照してください。
_=>
_は、型シグネチャの2つの部分を分離します。
したがって、_(Num a, Ord a) => a -> (t -> t) -> t -> t
_は、「タイプはa -> (t -> t) -> t -> t
であり、Num
の場合はa
インスタンス、Ord
の場合はa
インスタンスが必要です」という意味と考えることができます。
タイプクラスの詳細については、 http://www.learnyouahaskell.com/types-and-typeclasses を参照してください。
それについて考える1つの方法は、Ord a
およびNum a
は関数への追加入力です。ただし、これらは特別な種類の入力です:辞書。この関数を特定のタイプa
で使用する場合は、タイプOrd
のNum
およびa
操作でも使用できるdictionariesが必要です。
辞書入力を持つ関数を使用する関数も、同じ辞書入力を持っている必要があります。
foo :: (Num a, Ord a) => a -> t
foo x = loop x someFunc someT
ただし、これらの辞書を明示的に渡す必要はありません。利用可能な辞書があると仮定して、Haskellがそれを処理します。 typeclassインスタンスで辞書を作成できます。
instance Num MyType with
x + y = ...
x - y = ...
...
これにより、Num
に対するMyType
操作の辞書が作成されるため、MyType
はNum a
は必須の入力です(もちろん、他の要件を満たしていると仮定します)。
=>
の左側で、右側で使用されるタイプの制約を宣言します。
あなたが与える例では、それはa
がOrd
型クラスとNum
型クラスの両方のインスタンスであるように制約されていることを意味します。