You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Haskell如何读取用户输入传入toDigits函数拆分7位数字为整数列表

Haskell实现用户输入数字拆分为单个数字列表

需求说明

实现逻辑提示用户输入7位数字,将输入数字转换为单个整数组成的列表,预期运行效果:

toDigits 1234567 = [1, 2, 3, 4, 5, 6, 7]
toDigitsReverse 1234567 = [7, 6, 5, 4, 3, 2, 1]

注意:示例中的1234567需由用户动态输入,不可硬编码。

现存问题

已分别实现数字拆分逻辑和输入输出框架,但无法将两部分逻辑结合,初始硬编码版本代码如下:

toDigits :: Integral x => x -> [x]
toDigits 0 = []
toDigits x = toDigits (x div 10) ++ [x mod 10]

main :: IO ()
main = do 
    putStr "The split array is "
    print(toDigits 1234567)

尝试接入用户输入的版本运行时报错,代码如下:

toDigits :: Integer -> [Int]
toDigits n = map (\x -> read [x] :: Int) (show n)

main :: IO ()
main = do
    putStrLn "Please enter the USI number: "
    usi <- getLine
    let usiasnumber = read usi :: Int
    print("The USI split into single digit array is " ++ toDigits usiasnumber) 

运行返回错误:

Couldn't match type ‘Int’ with ‘Char’ Expected type: [Char] Actual type: [Int]

错误原因

  • 核心类型错误:Haskell中++运算符要求两侧列表的元素类型完全一致,拼接逻辑左侧的提示文本是String类型(即[Char]),右侧toDigits返回值是[Int]类型,两类列表无法直接拼接。
  • 初始版本语法错误:div、mod作为中缀运算符使用时,必须用反引号包裹,正确写法为x `div` 10、x `mod` 10,直接写x div 10会被编译器识别为未定义的普通标识符。

修正后可运行代码

-- 正序拆分数字为单个整数列表
toDigits :: Integral x => x -> [x]
toDigits 0 = []
toDigits x = toDigits (x `div` 10) ++ [x `mod` 10]

-- 逆序拆分直接复用正序逻辑反转结果即可
toDigitsReverse :: Integral x => x -> [x]
toDigitsReverse = reverse . toDigits

main :: IO ()
main = do 
    putStr "Please enter 7 digits: "
    -- 直接读取整数类型输入,无需手动getLine后转类型
    input <- readLn :: IO Int
    -- 非字符串值拼接前需用show转为字符串
    putStrLn $ "The split array is " ++ show (toDigits input)
    putStrLn $ "The reversed split array is " ++ show (toDigitsReverse input)

补充说明

  • 若需要严格校验输入为7位数字,可在读取输入后判断数值是否在1000000~9999999区间内,不符合要求则提示用户重新输入。
  • readLn可以直接读取指定类型的IO输入,比getLine后手动调用read的写法更简洁。
  • 所有非字符串类型的值要和字符串拼接时,必须先通过show方法转为对应字符串表示。

内容的提问来源于stack exchange,提问作者Justin Thomas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 06:03:13