質問
私は与えられたリスト内のすべての数値の階乗を計算し、それを画面に出力しHaskellの関数を書いています。
factPrint list =
if null list
then putStrLn ""
else do putStrLn ((show.fact.head) list)
factPrint (tail list)
機能が動作しますが、私は三行目のビットが混乱を見つけます。 なぜコンパイラ(GHC)は「putStrLn」(準?)関数の前に何が「やる」が存在しないため、それにエラーを報告していませんか? 私は省略した場合、予想通り4ラインから、エラーがポップアップし、「やる」。
私は、Haskellのとそのやり方に非常に新しいです、私は過度に愚かな何かを言っている場合ので、私はご容赦願います。
解決
do putStrLn ((show.fact.head) list)
factPrint (tail list)
は、実際に執筆のもう一つの方法である。
putStrLn ((show.fact.head) list) >> factPrint (tail list)
は、順番に、手段
putStrLn ((show.fact.head) list) >>= \_ -> factPrint (tail list)
do
表記は、この他の醜い構文なしで、一緒にこれらのモナドのストリングの便利な方法である。
あなただけdo
内の1文を持っている場合は、あなたが一緒に何かを架線されていない、とdo
が冗長である。
他のヒント
あなたはHaskellのに慣れていない場合、Cに似た言語でdo
後に必要なブレースと同様にif
を考える:
if (condition)
printf("a"); // braces not required
else {
printf("b"); // braces required
finish();
}
do
ハスケルで同じように動作します。
多分それはfactPrintの種類を見て助け、その後、使用パターンマッチングにリファクタリングなります:
factPrint :: [Int] -> IO ()
factPrint [] = putStrLn ""
factPrint list = do
putStrLn (show.fact.head) list
factPrint (tail list)
factPrintはIO ()
を返し、putStrLn ""
の種類がIO ()
であれば、そう、それは等しいfactPrint []
にputStrLn ""
のための完全に合法です。何do
は必要ありません - あなたは末尾の改行をしたくなかった場合は、実際には、あなただけのfactPrint [] = return ()
を言うことができる。
do
は一緒に複数の単項表現を結びつけるために使用されます。それは1つの式だけが続いても効果はありません。
よく形成しようとする場合のためには、then節および他の節は同じ型を持っていることだけが必要です。両方の句は、型IO ()
を有するので、このような場合である。
キーワード配列決定のために使用されているか、Haskellではされたif-then-elseは全くdo
が含まれている必要はありません。
if a
then b
else c
あなたが他のブランチ上の2つの操作を配列決定しているように、あなたはあなたの例ではdo
を必要としています。あなたがdo
を省略した場合、その後factPrint(tail list)
文は機能の一部ではないとみなされ、それが予想外の文に遭遇していますようので、コンパイラは文句を言います。