質問

私は与えられたリスト内のすべての数値の階乗を計算し、それを画面に出力し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)文は機能の一部ではないとみなされ、それが予想外の文に遭遇していますようので、コンパイラは文句を言います。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top