gpt4 book ai didi

haskell - Haskell 中 fromJust 的理由

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

我正在尝试学习 Haskll,所以我在 Haskell 中尝试了 Project Euler 的问题 26:
http://projecteuler.net/problem=26

我对这个问题的解决方案是这样的:

answer26 = answer26' 1000
answer26' n = snd $ maximum $ map (\x -> cycleLength x [1]) [2..n - 1]
where
cycleLength n (r:rs)
| i /= Nothing = (1 + fromJust i, n)
| r < n = cycleLength n $ (10*r):r:rs
| otherwise = cycleLength n $ (r `mod` n):r:rs
where i = elemIndex r rs

我意识到这不是最有效的算法,但认为它是天真的 O(n^3)(其中 n = 1000),这不是一个问题。不过,我担心的是,根据我对 monad 的理解,它们的主要属性之一是它们在某种意义上“标记”了任何使用过 monad 的东西。函数“fromJust”似乎直接面对它。它为什么存在?另外,假设它的存在是合理的,我在上面的代码中使用它是好的做法吗?

最佳答案

通常不鼓励使用部分函数(可能不返回值的函数)。类似 head 的函数和 fromJust存在是因为它们偶尔方便;您有时可以编写更短的代码,这对学习者来说更容易理解。许多函数算法都用 head 表示和 tailfromJust在概念上与 head 相同.

通常最好使用模式匹配并避免偏函数,因为它允许编译器为您捕获错误。在您的代码片段中,您仔细检查了该值从不 Nothing ,但在现实生活中的大型代码库中,代码可能已经有很多年了,有 1000 多行代码并且由许多开发人员维护。开发人员很容易重新订购一些代码而错过这样的检查。使用模式匹配,它就在代码结构中,而不仅仅是在一些任意的 Bool 表达式中。

替换您对 fromJust 的使用并不太难使用模式匹配:

answer26 = answer26' 1000
answer26' n = snd $ maximum $ map (\x -> cycleLength x [1]) [2..n - 1]
where
cycleLength n (r:rs) = case elemIndex r rs of
Just i -> (1 + i, n)
Nothing -> if r < n
then cycleLength n $ (10*r):r:rs
else cycleLength n $ (r `mod` n):r:rs

而且(我认为)结果也更清晰一些。

编辑:有一个明显“理论上可以”的地方可以使用 fromJustTypeclassopedia中提到,虽然你需要我以外的其他人来解释wtf那是关于..;)

关于haskell - Haskell 中 fromJust 的理由,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18288568/

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