首页 > 解决方案 > toDigits 但用零填充 Haskell

问题描述

我是 Haskell 的新手,有以下任务:

将正整数转换为其数字的列表,但如果列表有负数或为 0,则返回空列表。如果列表短于 9 位,则应从左侧用零填充。

我已经设法为填充和 for 编写代码toDigits,但我不确定如何组合它们,请帮忙。我的代码:

toDigits :: Integer -> [Integer]
toDigits 0 = []
toDigits x = (if (x < 0) then [] else (toDigits (x `div` 10)) ++ [x `mod` 10]) 

padLeft :: Int -> a -> [a] -> [a]  
-- I thought about calling the  function with 9 and 0 and the list
padLeft n x xs = replicate (n - length xs) x ++ xs

例子:

toDigits 496351 = [0,0,0,4,9,6,3,5,1]
toDigits 0 = []
toDigits (-17) = []

标签: haskellinteger

解决方案


您只需要再增加padLeft一个子句来扩充您的定义,以拦截这种[]情况:

padLeft' :: Int -> a -> [a] -> [a]  
padLeft' _ _ [] = ........    -- complete the definition
padLeft' n x xs = replicate (n - length xs) x ++ xs

现在,

> padLeft' 9 0 $ toDigits (496351)
[0,0,0,4,9,6,3,5,1]

> padLeft' 9 0 $ toDigits (-17)
[]

> padLeft' 9 0 $ toDigits (0)
[]

您可以将其打包为一个函数调用,

toDigitsPadded :: Integer -> [Integer]
toDigitsPadded n = padLeft' 9 0 $ toDigits n

或者,更短,

toDigitsPadded :: Integer -> [Integer]
toDigitsPadded  =  padLeft' 9 0 . toDigits

这就是我们在 Haskell 中从较小的函数组合更大的程序的方式。非巧合的是,该.运算符称为“函数组合运算符”,它从右到左组合两个函数,如上所示,因此第二个函数的输出(在“点”的右侧)用作第一个的输入(左侧):

(f  .  g) x  =  f (g x)

不是伪代码)。当使用显式参数时,这遵循通常的函数调用语法方向性。

还有一个从左到右的函数组合运算符,

(g >>> f) x  =  f (g x)
             =  g x & f
             =  x & g & f

这让我们在精神上更多地关注从左到右方向流经这些函数的数据。与运算符相同,&无非就是

x & g  =  g $ x 
       =  g  x

在任何特定时刻,哪个更有利于我们的思维过程。


推荐阅读