我正在写一个简单的函数来转换Integer为其各个数字的列表:
toDigits :: Integer -> [Integer]
toDigits 0 = [0]
toDigits n = [toInteger (digitToInt (show n !! x)) | x <- [0..(length (show n) - 1)]]
Run Code Online (Sandbox Code Playgroud)
我想链接
toInteger (digitToInt (show n !! x))
像点运算符一样:
toInteger . digitToInt . show . (!!) n x
Run Code Online (Sandbox Code Playgroud)
但是我觉得我对如何用点运算符编写这些函数有误解,因为这会产生难以理解的(对我的haskell-brain)类型错误
当涉及多参数函数时,无点样式开始变得混乱.可以说,像
(toInteger . digitToInt) $ show n !! x
Run Code Online (Sandbox Code Playgroud)
更具可读性.请继续阅读以获取此表达式的无点版本的一些示例.
首先,show n !! x实际上是(!!) (show n) x(因为函数应用程序具有更高的优先级(!!)),所以你不能直接编写show和(!!).相反,你可以写
toInteger (digitToInt ((!!) (show n) x))
Run Code Online (Sandbox Code Playgroud)
函数应用程序的优先级高于组合,因此您需要使用括号:
(toInteger . digitToInt . (!!)) (show n) x
Run Code Online (Sandbox Code Playgroud)
或者($)运算符,其优先级低于组合:
toInteger . digitToInt . (!!) $ (show n) x
Run Code Online (Sandbox Code Playgroud)
去有点疯狂,你可以使用flip部分地适用(!!)于x第一,让你写
toInteger . digitToInt . (flip (!!)) x . show $ n
Run Code Online (Sandbox Code Playgroud)
去一点点更疯狂,使用Control.Arrow和uncurry定义,你可以应用到一个完全免费的点对点功能对 (n, x)
toInteger . digitToInt . (first show >>> uncurry (!!)) $ (n, x)
Run Code Online (Sandbox Code Playgroud)
这first show是一个带有一对(n, x)并返回的函数((show n), x).然后喂这对uncurry (!!); uncurry只需创建一个函数,该函数将一对作为输入而不是两个参数:
> :t (!!)
[a] -> Int -> a
> :t uncurry (!!)
([c], Int) -> c
Run Code Online (Sandbox Code Playgroud)