无法使用点运算符编写Haskell函数

时间:2016-04-25 16:12:43

标签: haskell

我正在编写一个简单的函数将Integer转换为其各个数字的列表:

toDigits :: Integer -> [Integer]
toDigits 0 = [0]
toDigits n = [toInteger (digitToInt (show n !! x)) | x <- [0..(length (show n) - 1)]]

我想链接

toInteger (digitToInt (show n !! x))

使用点运算符,如:

toInteger . digitToInt . show . (!!) n x

但是我觉得我对如何用点运算符编写这些函数有误解,因为这会产生难以理解的(对我的haskell-brain)类型错误

2 个答案:

答案 0 :(得分:5)

当涉及多参数函数时,无点样式开始变得混乱。可以说是像

这样的东西
(toInteger . digitToInt) $ show n !! x

更具可读性。请继续阅读以获取此表达式的无点版本的一些示例。

首先,show n !! x实际上是(!!) (show n) x(因为函数应用程序的优先级高于(!!)),因此您无法直接撰写show和{{1 }}。相反,你可以写

(!!)

函数应用程序的优先级高于组合,因此您需要使用括号:

toInteger (digitToInt ((!!) (show n) x))

(toInteger . digitToInt . (!!)) (show n) x 运算符,其优先级低于组合:

($)

有点疯狂,您可以先使用toInteger . digitToInt . (!!) $ (show n) x flip部分应用到(!!),然后让您写一下

x

稍微更多疯狂,使用toInteger . digitToInt . (flip (!!)) x . show $ n Control.Arrow来定义一个完全无点的函数,您可以将其应用于 uncurry

(n, x)

此处,toInteger . digitToInt . (first show >>> uncurry (!!)) $ (n, x) 是一个函数,它接受一对first show并返回(n, x)。然后这对被喂给((show n), x); uncurry (!!)只是创建一个函数,它将一对作为输入而不是两个参数:

uncurry

答案 1 :(得分:2)

最好投入时间来获得更好的功能,例如

show

解释

  

(:[])将整数转换为字符串,read转换每个字符串   将char转换为String,import Data.Char(digitToInt) toDigits = map digitToInt . show 将String转换回   整数,这两个函数映射到String的元素   原始整数的表示,所以我们得到的是   列表形式的整数数字。

在您自己的解决方案中,在下面的其他答案和评论中,您可以使用digitToInt进一步简化

1000