2017-10-27 5 views
-1

マップを使用してリストのリストを返そうとしています。しかし、私は間違いを続けている。私はmapが関数を取り、その関数を使用することを知っています。しかし、私はそれに誤りを続けている。haskellでmap関数を使用するには?

map (take 3) [1,2,3,4,5] 

これは、[1,2,3]、[2,3,4]、[3,4,5]返すことになって、それは

<interactive>:6:1: error: 
• Non type-variable argument in the constraint: Num [a] 
    (Use FlexibleContexts to permit this) 
• When checking the inferred type 
    it :: forall a. Num [a] => [[a]] 

このエラーが返されますなぜそれがヌルを打つのですか?

+0

'マップ(3テイク)(テイク3(尾は、[1,2,3,4,5]))' – 4castle

+0

待ち時間は、ここで何が起こっているのですか? –

+1

'map'は、サブリストではなく、マッピング関数の各呼び出しに一度に1つの項目だけを渡します。私のコードでは、最初の3つのサブリストを取得するために 'tail 3'と' take 3 'を使います。 – 4castle

答えて

7

はのエラーメッセージが言っている正確に何を見てみましょう。

map (take 3) [1, 2, 3, 4, 5] 
map

の型シグネチャは

map :: (a -> b) -> [a] -> [b] 

だから、aからbに関数を取り、[a]から[b]に関数を返しています。あなたの場合、関数はtake 3です。これはリストを取り、リストを返します。従ってabはともに[t]です。したがって、mapの2番目の引数は、リストのリスト[[t]]でなければなりません。今、Haskellは第2引数を見て、それが数字のリストであることを見ています。だから、「どのようにして数字をリストにすることができますか?」ハスケルはこれを行う良い方法を知らないので、それはどのタイプも知らないと文句を言う。Num [t]

は今、あなたがする何を意味するのかについては、私はそれがコメントで言及されたと考えています。 tails関数はリストを取り、そのリストのすべてのテールのリストを返します。したがって

tails [1, 2, 3, 4, 5] 
-- ==> [[1, 2, 3, 4, 5], [2, 3, 4, 5], [3, 4, 5], [4, 5], [5], []] 

ここで、各引数にtake関数を適用できます。

map (take 3) (tails [1, 2, 3, 4, 5]) 
-- ==> [[1, 2, 3], [2, 3, 4], [3, 4, 5], [4, 5], [5], []] 

私たちは欲しくないいくつかの付加価値を持っています。その中に3つの要素を持つ値だけが必要です。だから、フィルタを私たちが望むものから外しましょう。 filterは、述語(ブール値を返す関数)とリストを返すだけで、述語を満たす要素のみを含むリストを返します。述語はリストを取り、またはそのリストには3つの要素があります。

\x -> ...   -- We want only the lists 
\x -> length x ... -- whose length 
\x -> length x == 3 -- is exactly equal to 3 

だから、私たちの関数のではない。今は。

filter (\x -> length x == 3) (map (take 3) (tails [1, 2, 3, 4, 5])) 
-- ==> [[1, 2, 3], [2, 3, 4], [3, 4, 5]] 

filterには、[1]あなたが取得するimport Data.Listする必要があるかもしれないことに注意することを渡しますtails機能。

+0

詳細な回答ありがとう –

+2

このようなフィルタリングは、4castleが提案したように 'take 3'を使うよりもはるかに遅いです。 – dfeuer

関連する問題