2

私はHaskellを学んでいて、Haskellのいくつかの概念をテストするためにこのコードを書きました。

identifyThing :: [arg] -> String
identifyThing arg = "This looks like a " ++
    case arg of
        [] -> "empty list"
        [arg] -> "list"
        arg -> "something else"

main :: IO ()
main = putStrLn (identifyThing [])
    putStrLn (identifyThing [1..10]) 
    putStrLn (identifyThing ()) 
    putStrLn (identifyThing 1)

メイン宣言の最初の行でエラーが発生します:putStrLnに7つの引数を適用できません。これは、引数を次の行にラップしていないことをhaskellに伝える方法がわからないためだと思います。

誰かが私が間違ったことを見せてくれたらありがたいです。ありがとう。

4

2 に答える 2

7

より長い答えは、Haskellではラインをひとまとめにしてそれらが順番に機能することを期待することはできないということです。{}-スタイルブロックなどの構文ではなく、関数を使用して行をより大きな行に結合するdoための構文です。>>=したがってdo、実際に書くときは1行だけです。

main = putStrLn (identifyThing []) >>= \_ -> putStrLn (identifyThing [1..10]) >>= \_  -> putStrLn (identifyThing [1])

ただし、パターンマッチング(caseまたは複数の方程式を使用した同等の定義)は上から下に機能します。

Haskellの全体的な考え方は、垂直プログラムを書くことはできないということです。水平プログラムしか書くことができません:)そして通常、「垂直」プログラムをより短い「水平」プログラムに再定式化することができます。例えば

main = mapM_ (putStrLn . identifying) [[], [1..10], [1]]

「垂直に」言いたかったことを「水平に」言う別の方法です。

初心者にとってdo<-そしてreturn構成はかなり誤解を招くものです。したがって、、、>>=およびを使用してから>>、、、、およびおよびからの他の関数を使用してそれを短縮する方法を学習する必要があります。また、多くの場合、アルゴリズムを再設計できるため、そもそも「垂直」コードは不要になります。\ ->return<$><*>.liftM2Control.MonadControl.Applicative

あなたの例では、理解しやすい初心者のコードは次のようになります。

main = putStrLn (identifyThing [1..10]) >> putStrLn (identifyThing ()) >> putStrLn (identifyThing 1)
于 2012-10-01T11:47:42.267 に答える
4

mainの後に「do」と改行を使用して修正しました。

これが私がそれを機能させるために使用したものです(プログラムの他の部分も修正しました):

identifyThing :: [a] -> String
identifyThing arg = "This looks like " ++
    case arg of
        [] -> "an empty list"
        [x] -> "a list with one element"
        x -> "a list with more than one element"

main :: IO ()
main = do
    putStrLn (identifyThing [])
    putStrLn (identifyThing [1..10]) 
    putStrLn (identifyThing [()])
    putStrLn (identifyThing [1])
于 2012-10-01T07:58:19.500 に答える