オフサイドルール(if then else)

Haskellはオフサイドルールを採用しています.

showPair ([0,1,2], [10, 11, 12])

のように,リストのタプルを渡された時

([0,1,2], [10, 11, 12])

の様な文字列を返す関数を考えてみます.
空っぽのリストを渡された時は

nil

を表示することにします. とりあえず,if then elseを使って書いた以下のコードを読んでみてください.
とりあえず,3パターン作ってみました.

showPair0 :: ([Int], [Int]) -> String
showPair0 (fsts, snds) = "("
                         ++ if null fsts then "nil" else show fsts
                         ++ ","
                         ++ if null snds then "nil" else show snds
                         ++ ")"
                              
showPair1 :: ([Int], [Int]) -> String
showPair1 (fsts, snds) = "("
                         ++ if null fsts
                              then "nil"
                              else show fsts
                         ++ ","
                         ++ if null snds
                              then "nil"
                              else show snds
                         ++ ")"
                               

showPair2 :: ([Int], [Int]) -> String
showPair2 (fsts, snds) = "("
                         ++ (if null fsts
                             then "nil"
                             else show fsts)
                         ++ ","
                         ++ (if null snds
                            then "nil"
                            else show snds)
                         ++ ")"

test arg = do putStrLn $ "0:" ++  showPair0 arg
              putStrLn $ "1:" ++  showPair1 arg
              putStrLn $ "2:" ++  showPair2 arg

テストテスト

*Main> test ([0,1,2], [10, 11, 12])
0:([0,1,2],[10,11,12])
1:([0,1,2],[10,11,12])
2:([0,1,2],[10,11,12])

ははは当然動きますよ.(0が一昨日の私)

nilも表示してみよう

*Main> test ([0,1,2], [])
0:([0,1,2],nil
1:([0,1,2],nil
2:([0,1,2],nil)

ひひひ当然動きますよ.(0が一昨日の私)

昨日.
実際の環境で動かす.

*Main> test ([], [10,11,12])
0:(nil
1:(nil
2:(nil,[10,11,12])

わわわおかしな事になった.(0が昨日の私^^;)

さらに実際に動かしていたコードは,何も出力しないような事になってたので,焦る焦る.

原因は

if hoge then "hoge" else "hoe"
++ if foo then "foo" else "bar"

if hoge then "hoge"
        else ("hoe" ++ if foo then "foo" else "bar")

と扱われていたからなのですが,私の中のオフサイドルールの理解ではこんな事にはならないはずなのですが...

実際に使うコードはカッコまみれも嫌なのでlet inを使って

showPair_ok :: ([Int], [Int]) -> String
showPair_ok (fsts, snds) = let fstsTxt = if null fsts then "nil" else show fsts
                               sndsTxt = if null snds then "nil" else show snds
                           in "("
                                  ++ fstsTxt
                                  ++ ","
                                  ++ sndsTxt
                                  ++ ")"

な風にしておいた.
1日中,見当違いのミスを探していた.まさかこんなことで....

C/C++で

if(hoge) if(hoge2) puts("true true");
         else      puts("true false"); //実装依存

なミスはした事はなかったのに^^;(中カッコ付ける事がほとんど...)

ちなみにオフサイドルールだけで解決する方法は分からない(だめじゃん)
曖昧な表記はなるべくさけて,letかカッコで書くほうがよさげ.


お名前: