2017-05-11 6 views
4

私は効果的に[take 1,take 2,take 3]を持っているので、リストの各要素がタイプ[Int] -> [Int]であるように、関数のリストを作成しようとしています(後でzipwithと一緒に使う)。マップを使用して部分的に適用された関数のリストを作成するにはどうすればよいですか?

これは私が試したことであり、正しくなければならないと感じています。なぜ私はエラーメッセージが表示されているのか分かりません。

Prelude> map (\x -> take x) [1..5] 

<interactive>:46:1: 
    No instance for (Show ([a0] -> [a0])) 
     (maybe you haven't applied enough arguments to a function?) 
     arising from a use of ‘print’ 
    In a stmt of an interactive GHCi command: print it 
+6

エラーメッセージは、GHCiが結果の関数リストの印刷方法を知らないと言うだけです。表現自体に何も問題はありません。あなたは ':t'でそれのタイプを依頼することができます。それはうまくいくはずです。 – kosmikus

+1

また、lambda: 'map take [1..5]'も同様にうまく動作します。 – phg

答えて

3

まず、あなたのコードが動作します。しかし、関数はshowを得ることができません。試してみてくださいshow id、と非常に似たエラーメッセージが表示されます。

しかし、あなたの関数リストのアプリケーションを掘り下げる前に、ロジックが健全かどうかをチェックするだけで、型を見てみましょう。簡単のため、1 :: Intとします。また、\x -> take xはちょうどtakeなので、map take [1..5]であなたの行動を再現することができます。今、私たちはmaptakeを差し込む

map :: (a -> b   ) -> [a] -> [b] 
take :: Int -> ([c] -> [c])     -- explicit parentheses 

:今、私たちは私たちの小さなタイプの混乱の中で、次の参加者があります。 mapでは、takeの最初の引数のためにa ~ Intであり、b ~ [c] -> [c]です。

map take  :: [Int] -> [[c] -> [c]] 
[1..5]   :: [Int] 
map take [1..5] ::   [[c] -> [c]] 

そして、我々が行っている:したがって、我々は今、我々は単に私たちの上の行にタイプを削除map take [1..5]を、使用

map take :: [Int] -> [[c] -> [c]] 

を持っています。私たちはあなたのエラーメッセージとまったく同じタイプになります。すべてがうまくいくのでしょうか? はい。あなたのコードには何も問題はありません。

しかし、既に述べたように、[[c] -> [c]]は表示できません。

Prelude> map (\f -> f [1..10]) (map take [1..5]) 
[[1],[1,2],[1,2,3],[1,2,3,4],[1,2,3,4,5]] 
1

@kosmikusコメントにあなたの質問に答えが、ここではケースには誰もが興味を持っている:tがコンソールにして何をするかです:私たちはあなたのリストにそれらの機能を適用する必要があります。ここで

は、あなたが望んでいた5つの関数のリストで、直接入力:

Prelude> :t [(take 1), (take 2), (take 3), (take 4), (take 5)] 
[(take 1), (take 2), (take 3), (take 4), (take 5)] :: [[a] -> [a]] 

mapであなたの式を使用:

Prelude> :t map (\x -> take x) [1..5] 
map (\x -> take x) [1..5] :: [[a] -> [a]] 

ちなみに、あなたも言うことができる:

Prelude> :t map take [1..5] 
map take [1..5] :: [[a] -> [a]] 

あなたができないのは、GHCIコンソールに値そのものをレンダリングすることです.nリストから関数をリストに表示する方法。 @ kosmikusによる:tのトリックは素晴らしいです。つまり、の機能のリストを使用して実際にそれらを見ることができます。たとえば、次のようにリスト[8 9 10 11]に機能take 2を適用

Prelude> let takers = map take [1..5] in head(tail takers) [8,9,10,11] 
[8,9] 

関連する問題