離れて、この何とか抽象化することが可能ですそのようなことは、this oneなどの回答に記載されています。しかし多くの場合、タイプシグネチャについてわかっていることを注意深く見てみると、それを把握する必要があります。
unsafeListHandling :: [a] -> ([a] -> a) -> Maybe a
unsafeListHandling2 :: [a] -> ([a] -> [a]) -> Maybe [a]
我々は一般unsafeListHandling
について知っているもの:
- その最初の引数は、任意のタイプのリストでなければなりません(あなたが課せられている要件としてそれを見てみましょう)。
- このタイプのリストでは、2番目の引数として関数を使用する必要があります。
- 2番目の引数の結果の型に一致する
Maybe
を生成する必要があります。
- 2番目の引数の結果の型を、最初の引数の(リスト)型または対応する要素の型(2つのシグネチャの違いをカバーする)のいずれかに特化できます。
我々は型シグネチャとしてそれを書き留めた場合は、我々が得る:
unsafeListHandling :: [a] -> ([a] -> b) -> Maybe b
をa
は任意であり、かつb
がb ~ [a]
とb ~ a
の両方が有効な専門分野であるようなもので。 b
を文字通り無制限の自由変数とみなすと、[a]
またはa
のいずれかに特化することはありません。であることはそう、一般的な型シグネチャは確かであること:
unsafeListHandling :: [a] -> ([a] -> b) -> Maybe b
unsafeListHandling xs fx = if null xs then Nothing else Just $ fx xs
我々はメルポメネの提案に従い、任意の署名を追加することなく、GHCiのあなたの関数の種類を尋ねたら...
GHCi> :t \xs fx -> if null xs then Nothing else Just $ fx xs
\xs fx -> if null xs then Nothing else Just $ fx xs
:: Foldable t => t a -> (t a -> a1) -> Maybe a1
...我々が得ます疑問の余地のある一般化を除いて[a]
からFoldable t => t a
までです。これはnull
のタイプがFoldable t => t a -> Bool
であるために発生します。あなたはGHC 8を使用している場合はところで、あなたはTypeApplications
拡張を有効にすることができますし、あなたのタイプのテトリスの目的のためにnull
を専門とする便利な方法としてそれを使用します、一般化デモを物事をラップするには
GHCi> :set -XTypeApplications
GHCi> :t \xs fx -> if null @[] xs then Nothing else Just $ fx xs
\xs fx -> if null @[] xs then Nothing else Just $ fx xs
:: [a] -> ([a] -> a1) -> Maybe a1
関数は実際にあなたが望むものを実行します:
GHCi> (\xs fx -> if null @[] xs then Nothing else Just $ fx xs) [1..7] head
Just 1
GHCi> (\xs fx -> if null @[] xs then Nothing else Just $ fx xs) [1..7] tail
Just [2,3,4,5,6,7]
型シグネチャを削除して、推論型のghciを求めます。 – melpomene
これは一方の方法ですが、より一般的な関数定義にすることは可能でしょうか?私はどんな解決法ではなく技術を求めています – MrX
言語拡張を使用しない場合、Haskellは最も一般的な型を推論します。 (いくつかの例外があります。たとえば、多形的な再帰を推論できるとは思いません。) – melpomene