gpt4 book ai didi

haskell - 关于Haskell运算符优先级和函数组合的解释

转载 作者:行者123 更新时间:2023-12-02 21:26:16 25 4
gpt4 key购买 nike

我需要一些帮助来理解“列表复制”Hackerrank 挑战的 Haskell 模板。我不明白函数执行的顺序。

f = concatMap . replicate

-- This part handles the Input and Output and can be used as it is.
main :: IO ()
main = getContents >>=
mapM_ print . (\(n:arr) -> f n arr) . map read . words

getContents函数应该产生 IO String喜欢 "2\n1\n2\n3\n4\n5\n6\n7\n8\n9\n10" 。我大致了解接下来会发生什么,但我不明白按什么顺序和优先顺序。我尝试执行words "2\n1\n2\n3\n4\n5\n6\n7\n8\n9\n10在 ghci 中并将结果输入 map read 。但后来我得到了结果 "[*** Exception: Prelude.read: no parse" 。如果我尝试 map read . words "2\n1\n2\n3\n4\n5\n6\n7\n8\n9\n10"我得到结果"Couldn't match expected type ‘a -> [String]’ with actual type ‘[String]’" 。整个组合的 main 函数怎么不会抛出错误?

如果有人能帮助我理解整个主要功能,我将非常感激。特别是哪些函数以哪些输入的顺序执行,以及如何将其分割成更小的(工作!)部分以更好地理解它。

非常感谢!

最佳答案

在 GHCi 提示符下定义

g = (\(n:arr) -> f n arr)
where
f = concatMap . replicate

我们将派生类型返回为 g::[Int] -> [Int]。这将 map read 中的 read 类型定义为 String -> Int,并且一切正常。以更易读的形式更容易理解,

g :: [Int] -> [Int]
g (n:arr) = concatMap (replicate n) arr

类型 Int 是由 n::Int 派生的,因为 replicate::Int -> a -> [a],并且arr 以及 (n:arr)::[Int] 的类型由此而来,因为 Haskell 列表是同类的,即具有相同类型的所有元素。

最常见的read类型是read::Read a => String -> a。事实上 Int 属于 Read 类型类。

但是如果我们不知道这是一个 IntDouble 还是其他类型怎么办?然后 read 不知道要解析哪种格式,因此我们收到 “read: no parse” 错误消息。

这就是我们尝试时会发生的事情

(map read . words) "2\n3\n4\n"  =  map read $ words "2\n3\n4\n" 
= map read (words "2\n3\n4\n")

当我们打开括号时,$ 出现在此处,而不是 .。由于运算符优先级,您的 main 函数实际上是

main :: IO ()
main = getContents >>=
(mapM_ print . (\(n:arr) -> f n arr) . map read . words)
= getContents >>= (\s ->
(mapM_ print . g . map read . words) s)
= getContents >>= (\s ->
mapM_ print $ g $ map read $ words s)

使用 . 而不是 $ ,就像你所做的那样是错误的,因为仅仅省略这些括号是错误的,会导致与函数相关的其他错误消息,如 . 期望一个函数作为右侧的参数,但 ["2","3","4"] 不是一个函数。

关于haskell - 关于Haskell运算符优先级和函数组合的解释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58051838/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com