HaskellでAOJ ITP1_2_A大小関係
Haskellの練習がてらAOJをちまちま解いてみる。
とりあえずトップページから
誰かが解いてる問題に適当に飛んで行けそうなら解くという方針。
早速最初の問題は
大小 等価 | プログラミング入門 | Aizu Online Judge
2つの整数 a, b を読み込んで、a と b の大小関係を出力するプログラムを作成して下さい。
ふむふむ
これくらいならググりながら解けばなんとかなりそうだ。
いきなり詰む
main = do s <- getLine let [a,b] = map read $ words s if (a > b) then do print "a > b" else if (a < b) then do print "a < b" else print "a == b"
こんな感じで書いてみたのだが
コンパイルエラー
Ambiguous type variable ‘a0’ arising from a use of ‘read’ prevents the constraint ‘(Read a0)’ from being solved.
Relevant bindings include
a :: a0 (bound at ITP1_2_A.hs:3:8)
b :: a0 (bound at ITP1_2_A.hs:3:10)
Probable fix: use a type annotation to specify what ‘a0’ should be.
These potential instances exist:
instance Read Ordering -- Defined in ‘GHC.Read’
instance Read Integer -- Defined in ‘GHC.Read’
instance Read a => Read (Maybe a) -- Defined in ‘GHC.Read’
...plus 22 others
...plus four instances involving out-of-scope types
(use -fprint-potential-instances to see them all)
早くもギブアップ
型に関するエラーらしいのだが
訳がわからないのでチラッと回答例を参考にする事にした。
yoshさんの回答を参考に自分のコードに取り入れる。
解決策が判明
どうやら
let [a,b] = map read $ words s
という部分を
let [a,b] :: [Int] = map read $ words s
といった具合に書き換えて型を明示すれば良いらしい。
しかし単に::[Int]を加えただけだと
Illegal type signature: ‘[Int]’ Type signatures are only allowed in patterns with ScopedTypeVariables
というエラーが出てしまうので
ファイルの先頭に
{-# LANGUAGE ScopedTypeVariables #-}
ScopedTypeVariablesという言語拡張を加えてエラーを回避する。
参考 Scoped type variablesが必要になるとき - maoeのブログ
これghcじゃなかったらどう解決するのだろうか。
深く考えるのは後にしてとりあえずコードを手直し
{-# LANGUAGE ScopedTypeVariables #-} main :: IO () main = do s <- getLine let [a,b]::[Int] = map read $ words s if a > b then print "a > b" else if a < b then print "a < b" else print "a == b"
IDEに注意された箇所も修正して
出来上がった上記のコードを判定に突っ込む。
駄目じゃん!!
間違いの原因を探る
手元でrunghcをして動かしてみると
10 1 "a > b"
このような出力になっていた。
おそらく"が邪魔なのだろう。
printをputStrLnに変更
{-# LANGUAGE ScopedTypeVariables #-} main :: IO () main = do s <- getLine let [a,b]::[Int] = map read $ words s if a > b then putStrLn "a > b" else if a < b then putStrLn "a < b" else putStrLn "a == b"
今度は通った。
全然スマートではないけど。