2017-02-25 4 views
-3

は何とか次のコードは、より汎用的なスニペットにすることが可能であり、我々は基本的に同じコードで2つの機能を持っている、唯一の違いは、関数定義され、体系的な方法同じ定義を持つこれらの2つの関数に、より一般的な型を与えるにはどうすればよいですか?

unsafeListHandling :: [a] -> ([a] -> a) -> Maybe a 
unsafeListHandling xs fx = if null xs then Nothing else Just $ fx xs 

unsafeListHandling2 :: [a] -> ([a] -> [a]) -> Maybe [a] 
unsafeListHandling2 xs fx = if null xs then Nothing else Just $ fx xs 
+5

型シグネチャを削除して、推論型のghciを求めます。 – melpomene

+0

これは一方の方法ですが、より一般的な関数定義にすることは可能でしょうか?私はどんな解決法ではなく技術を求めています – MrX

+0

言語拡張を使用しない場合、Haskellは最も一般的な型を推論します。 (いくつかの例外があります。たとえば、多形的な再帰を推論できるとは思いません。) – melpomene

答えて

3

離れて、この何とか抽象化することが可能ですそのようなことは、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は任意であり、かつbb ~ [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] 
+0

ありがとう非常に洞察力のある – MrX

関連する問題