接受输入列表

时间:2012-02-07 10:07:13

标签: haskell

我想接受用户的5个值。但是,在我的代码(下面)中,如果我输入像[1,2,3,4,5]这样的列表,我会收到错误消息。例如,此代码仅接受[999]形式的输入。

有谁知道如何解决这个问题?

putStrLn("Enter 5 binary numbers [,,] : ")
    input<-getLine
    let n=(read input)::[Int]
    let result = convertionTO binaryToDec n
    putStrLn(show result)

在上面的代码中,行let n=(read input)::[Int]只接受用户输入[999]或其他什么作为一个输入。有没有办法输入值列表?

使用行let result = convertionTO binaryToDec n我试图将二进制值列表转换为十进制值

2 个答案:

答案 0 :(得分:2)

您要求使用[Int]将输入转换为read,因此使用与Haskell源代码相同的规则进行转换,这意味着它们将被解析为十进制数字

由于您要将它们解析为二进制数字,您必须编写自己的String -> Int(或允许错误,String -> Maybe Int)函数将它们转换为Int s来自二进制文件。

十进制数和二进制数之间没有区别。只有数字。十进制或二进制是数字如何表示为字符串的工件。

答案 1 :(得分:0)

您可以在newtype周围放置一个Integer包装,为其提供自己的ReadShow个实例。这样,您仍然可以使用列表解析器,但用您自己的解析器替换元素:

{-# LANGUAGE GeneralizedNewtypeDeriving #-}

import Numeric ( readInt, showIntAtBase )
import Data.Char ( digitToInt, intToDigit )
import Control.Arrow ( first )

newtype BinNum = BinNum { unBinNum :: Integer }
  deriving ( Eq, Ord, Num )

main = do
  putStrLn "Enter 5 binary numbers [,,] :"
  input <- getLine
  let ns = read input :: [BinNum]
      result = map unBinNum ns
  putStrLn $ show result

isBinDigit :: Char -> Bool
isBinDigit c = c >= '0' && c <= '1'

readBinNum :: ReadS BinNum
readBinNum = map (first BinNum) . readInt 2 isBinDigit digitToInt

showBinNum :: BinNum -> ShowS
showBinNum = showIntAtBase 2 intToDigit . unBinNum

instance Read BinNum where
  readsPrec _ = readBinNum

instance Show BinNum where
  showsPrec _ = showBinNum