私はHaskellを初めて使用し、基本を学ぼうとしています。リストの内容を操作する方法を理解するのに苦労しています。
次のリストがあり、リスト内のすべての要素から1を引く関数を作成したいとします。ここで、xを関数に渡すだけで、これはどのように行われますか?
Prelude>let x = 1:2:3:4:5:[]
何かのようなもの:
Prelude>subtractOne(x)
私はHaskellを初めて使用し、基本を学ぼうとしています。リストの内容を操作する方法を理解するのに苦労しています。
次のリストがあり、リスト内のすべての要素から1を引く関数を作成したいとします。ここで、xを関数に渡すだけで、これはどのように行われますか?
Prelude>let x = 1:2:3:4:5:[]
何かのようなもの:
Prelude>subtractOne(x)
(より簡単に、またはさらに1:2:3:4:5:[]
簡単に書くことができます。)[1,2,3,4,5]
[1..5]
リスト内包表記を使用したいので、ここにあります:
subtractOne xs = [ x-1 | x <- xs ]
ここではxs
、1を引いているリストを表すために使用しています。
最初に気付くのは、「から取ったもの」x <- xs
として読むことができるということです。これは、それぞれの番号を順番に取得し、そのたびに番号に電話をかけることを意味します。x
xs
xs
x
x-1
は、それぞれについて計算して返す値ですx
。
その他の例として、各要素に1つ追加するか、各要素を[x+1|x<-xs]
2乗する例を示します[x*x|x<-xs]
。
リスト内包表記をもう少し詳しく見てみましょう。平方を見つけてから、与えた数の立方体を見つける関数を作成します。
> squaresAndCubes [1..5]
[1,4,9,16,25,1,8,27,64,125]
必要です
squaresAndCubes xs = [x^p | p <- [2,3], x <- xs]
これは、累乗p
を2、次に3とし、各累乗について、からすべてのx
sを取得し、累乗( )xs
で計算することを意味します。x
p
x^p
逆にするとどうなりますか?
squaresAndCubesTogether xs = = [x^p | x <- xs, p <- [2,3]]
我々が得る
> squaresAndCubesTogether [1..5]
[1,1,4,8,9,27,16,64,25,125]
これはそれぞれを取りx
、次にそれの2つの力を次々に与えます。
結論-<-
ビットの順序は、出力の順序を示します。
一部の回答のみを許可したい場合はどうなりますか?
2から100までのどの数字を次のように書くことができますx^y
か?
> [x^y|x<-[2..100],y<-[2..100],x^y<100]
[4,8,16,32,64,9,27,81,16,64,25,36,49,64,81]
ここでは、限りx
すべてを許可しました。y
x^y<100
各要素に対してまったく同じことをしているので、実際にはmap
:を使用してこれを記述します。
takeOne xs = map (subtract 1) xs
またはより短い
takeOne = map (subtract 1)
(負の1として解析されるsubtract 1
ため、これを呼び出す必要があります。)- 1
map
これは、次の関数を使用して実行できます。
subtractOne = map (subtract 1)
リスト内包表記を使用した代替ソリューションは、もう少し冗長です。
subtractOne xs = [ x - 1 | x <- xs ]
わかりやすくするために、タイプ注釈を追加することもできます。
この関数を使用すると、これを非常に簡単に行うことができますがmap
、学習演習として自分で何かを転がしたいと思うでしょう。Haskellでこれを行う1つの方法は、再帰を使用することです。これは、関数を2つのケースに分割する必要があることを意味します。最初のケースは通常、最も単純な種類の入力の基本ケースです。リストの場合、これは空のリスト[]
です。空のリストのすべての要素から1を引いた結果は、明らかに空のリストです。Haskellの場合:
subtractOne [] = []
ここで、もう少し複雑な再帰の場合を検討する必要があります。空のリスト以外のリストについては、入力リストの先頭と末尾を確認できます。頭から1を引いてsubtractOne
、リストの残りの部分に適用します。次に、結果を連結して新しいリストを作成する必要があります。コードでは、これは次のようになります。
subtractOne (x:xs) = (x - 1) : subtractOne xs
前に述べたように、これは。で行うこともできますmap
。実際、それはたった1行であり、好ましいHaskellismです。一方で、それがどのように機能するかを理解するために、明示的な再帰を使用する独自の関数を作成することは非常に良い考えだと思います。最終的には、map
さらに練習するために独自の関数を作成することもできます。
map (subtract 1) x
動作します。
subtractOne = map (subtract 1)
このmap
関数を使用すると、リストの各要素に関数を適用できます。