5

引数として渡された関数を 2 つの異なる型に適用する方法はありますか? 不自然な例として、(Maybe Int, Maybe Bool)(Just 3, Just True)で を作成できますが、関数でこの動作をより一般的にしようとすると

generic :: (a -> Maybe a) -> (Maybe Int, Maybe Bool)
generic f = (f 3, f True)

のようなことができるようにするには、型変数が定数であるgeneric Justため、コンパイラが文句を言います。a

これの使用例は、各ノードがタイプによってパラメーター化されているツリー構造にジェネリック関数を適用することです。

4

1 に答える 1

10

これは、次のようにランク 2 ポリモーフィズムを使用して実現できます。

{-# LANGUAGE Rank2Types #-}
generic :: (forall a. a -> Maybe a) -> (Maybe Int, Maybe Bool)
generic f = (f 3, f True)

多くの場合、型クラスの制限が必要になります (の実装がgeneric要求するためではなく、呼び出し元がすべての型に対して機能する引数を渡すことができないため)。

genericNum :: (forall a. Num a => a -> a) -> (Int, Integer)
genericNum f = (f 3, f 9)
于 2016-02-05T04:00:51.360 に答える