LoginSignup
14
0

More than 3 years have passed since last update.

Haskell コマンドライン引数を数値にする

Last updated at Posted at 2019-11-30

今回初めてHaskellでコーディングをしたのですが、「コマンドラインから受け取った引数を数値にする」でつまづきました

コマンドラインからの引数は IO String配列

@taashi さんの記事をお手本にしました! Haskellでコマンドライン引数を受け取る

import System.Environment (getArgs)

main = do
    args <- getArgs
    let str_num = args !! 0
        num = read str_num :: Int
    print num > 100

引数をStringからIntにして「100より大きい数か」表示したかったのですが、コンパイルエラー
コマンドラインからの入力はIO String型でString型とはちがうから
num = read str_num :: IntではInt型になっていないようです
print (num > 100)としていないのが原因
(print num) > 100と解釈され、標準出力に表示してから(IO~型)100より大きいかを判定しようとしているからエラー
@tezca686 さん教えてくれてありがとうございます)

>stack ghc test.hs
[1 of 1] Compiling Main             ( test.hs, test.o )

test.hs:15:5: error:
    ? Couldn't match expected type ‘IO b’ with actual type ‘Bool’
    ? In a stmt of a 'do' block: print num > 100
      In the expression:
        do args <- getArgs
           let str_num = args !! 0
               num = ...
           print num > 100
      In an equation for ‘main’:
          main
            = do args <- getArgs
                 let str_num = ...
                     ....
                 print num > 100
    ? Relevant bindings include main :: IO b (bound at test.hs:11:1)
   |
15 |     print num > 100
   |

これでできた!

main関数では引数を受け取って結果を表示するだけにしました
doブロック内だとコンパイラーがIO~型として認識するのでしょうか??

import System.Environment (getArgs)

-- StringからIntに変換
convert :: String -> Int
convert x = read x :: Int

-- 100より大きいか判定
compare_hun :: Int -> Bool
compare_hun x = 100 < x

main = do
    args <- getArgs
    let str_num = args !! 0
        num = convert str_num
        result = compare_hun num -- 判定結果を変数に保存
    print result
>stack ghc test.hs
[1 of 1] Compiling Main             ( test.hs, test.o )
Linking test.exe ...

>test.exe 100
False

>test.exe 101
True

ちょっと応用

私がコーディングしたのは、コマンドラインから入力された「クリスマスプレゼントの予算」が
2019年クリスマスプレゼントの平均予算(勝手に予測)と比較して高いか安いかを表示する関数です!
日本語だとUnicodeが表示されるのでメッセージを英語にしています
printではなくputStrだと日本語も表示できました!@mod_poppo さんありがとうございます)
コード、英語アドバイスお願いします

import System.Environment (getArgs)

convert :: String -> Int
convert x = read x :: Int

compare_to_avg :: Int -> String
compare_to_avg x =
    if x < 12477
      then "smart shopper!!"
    else if x < 15000
      then "GRATE sense of money!!!"
    else
      "How nice! Happy Holidays!"

main = do
    args <- getArgs
    let str_price = args !! 0
        price = convert str_price
        result = compare_to_avg price
    print "Budget of Holidays gift in 2019(avg):12,477JPY"
    print result

希望をこめて20,000円と入力しました 最高のホリデーシーズンをお過ごしください!!!

>xmas_gift.exe 20000
"Budget of Holidays gift in 2019(avg):12,477JPY"
"How nice! Happy Holidays!"
14
0
5

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
0