getArgs 字符串转int
getArgs string to int
我正在尝试在 haskell 中编写我的第一个 IO 程序,但我似乎无法从命令行 运行
我想要命令 cabal 运行 5 > result.txt 在 result.txt 中打印二进制 5。我找到了一些转换代码,但是当我实现它时出现错误:
src/Main.lhs:23:28: error:
• Couldn't match type ‘Int’ with ‘Char’
Expected type: String
Actual type: [Int]
• In the second argument of ‘writeFile’, namely ‘(toBin (args))’
In a stmt of a 'do' block: writeFile "file.txt" (toBin (args))
In the expression:
do { args <- getArgs;
writeFile "file.txt" (toBin (args)) }
src/Main.lhs:23:34: error:
• Couldn't match expected type ‘Int’ with actual type ‘[String]’
• In the first argument of ‘toBin’, namely ‘(args)’
In the second argument of ‘writeFile’, namely ‘(toBin (args))’
In a stmt of a 'do' block: writeFile "file.txt" (toBin (args))
这是我的代码:
module Main where
import System.Environment
import Data.List
import Data.Maybe
import qualified Data.Map as M (Map, empty, insert, lookup)
import Data.Char (ord)
toBin:: Int -> [Int]
toBin 0 = [0]
toBin n = reverse (helper n)
helper:: Int -> [Int]
helper 0 = []
helper n = let (q,r) = n `divMod` 2 in r : helper q
main :: IO ()
main = do
args <- getArgs
writeFile "file.txt" (toBin(args))
First,你的函数 toBin
需要一个 Int
参数,但是 args
是 [String]
类型 - 即字符串列表。因此,您需要获取第一个参数(来自您的描述)并将其转换为 Int
。最便宜、最肮脏的方法是先使用 head
然后 read
转换为 Int
:
writeFile "file.txt" (toBin . read . head $ args)
但是请注意,如果 (1) 参数列表为空(即没有“第一个”元素)或 (2) 第一个参数不是数字,此代码将在运行时崩溃。如果您不同意崩溃,请考虑使用更安全的替代方案,例如 headMay
or reads
.
Second,你的函数 toBin
returns 是 Int
的列表,但是 writeFile
需要一个类型的参数String
。最便宜、最肮脏的转换方式是通过 show
:
writeFile "file.txt" (show . toBin . read . head $ args)
但是,show
列表的实现将产生一个看起来不像二进制数的字符串。它看起来像 "[0, 1, 1, 0, 1]"
。如果您对这种表示不满意,则必须编写自己的函数来将列表转换为看起来像二进制数的字符串。最便宜、最肮脏的方法是将 show
应用于列表的每个元素,然后将结果字符串粘合在一起:
binToStr :: [Int] -> String
binToStr = concat . map show
...
writeFile "file.txt" (binToStr . toBin . read . head $ args)
或者可以简化为concatMap
:
binToStr = concatMap show
我正在尝试在 haskell 中编写我的第一个 IO 程序,但我似乎无法从命令行 运行 我想要命令 cabal 运行 5 > result.txt 在 result.txt 中打印二进制 5。我找到了一些转换代码,但是当我实现它时出现错误:
src/Main.lhs:23:28: error:
• Couldn't match type ‘Int’ with ‘Char’
Expected type: String
Actual type: [Int]
• In the second argument of ‘writeFile’, namely ‘(toBin (args))’
In a stmt of a 'do' block: writeFile "file.txt" (toBin (args))
In the expression:
do { args <- getArgs;
writeFile "file.txt" (toBin (args)) }
src/Main.lhs:23:34: error:
• Couldn't match expected type ‘Int’ with actual type ‘[String]’
• In the first argument of ‘toBin’, namely ‘(args)’
In the second argument of ‘writeFile’, namely ‘(toBin (args))’
In a stmt of a 'do' block: writeFile "file.txt" (toBin (args))
这是我的代码:
module Main where
import System.Environment
import Data.List
import Data.Maybe
import qualified Data.Map as M (Map, empty, insert, lookup)
import Data.Char (ord)
toBin:: Int -> [Int]
toBin 0 = [0]
toBin n = reverse (helper n)
helper:: Int -> [Int]
helper 0 = []
helper n = let (q,r) = n `divMod` 2 in r : helper q
main :: IO ()
main = do
args <- getArgs
writeFile "file.txt" (toBin(args))
First,你的函数 toBin
需要一个 Int
参数,但是 args
是 [String]
类型 - 即字符串列表。因此,您需要获取第一个参数(来自您的描述)并将其转换为 Int
。最便宜、最肮脏的方法是先使用 head
然后 read
转换为 Int
:
writeFile "file.txt" (toBin . read . head $ args)
但是请注意,如果 (1) 参数列表为空(即没有“第一个”元素)或 (2) 第一个参数不是数字,此代码将在运行时崩溃。如果您不同意崩溃,请考虑使用更安全的替代方案,例如 headMay
or reads
.
Second,你的函数 toBin
returns 是 Int
的列表,但是 writeFile
需要一个类型的参数String
。最便宜、最肮脏的转换方式是通过 show
:
writeFile "file.txt" (show . toBin . read . head $ args)
但是,show
列表的实现将产生一个看起来不像二进制数的字符串。它看起来像 "[0, 1, 1, 0, 1]"
。如果您对这种表示不满意,则必须编写自己的函数来将列表转换为看起来像二进制数的字符串。最便宜、最肮脏的方法是将 show
应用于列表的每个元素,然后将结果字符串粘合在一起:
binToStr :: [Int] -> String
binToStr = concat . map show
...
writeFile "file.txt" (binToStr . toBin . read . head $ args)
或者可以简化为concatMap
:
binToStr = concatMap show