- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我为一个非常简单的练习题写了一个解决方案:
Calculate the number of grains of wheat on a chessboard given that the number on each square doubles. Write code that shows how many grains are on a given square, and the total number of grains on the chessboard.
如果输入小于 1 或大于 64,该函数必须返回一个 Maybe Integer
并返回 Nothing
。
square :: Integer -> Maybe Integer
square n = if (n < 1 || n > 64) then Nothing else Just (2^(pred n))
total :: Integer
total = sum (fmap sum (map square [1..64]))
我尝试将 fmap sum
应用于 GHCI 中 map square
的一些测试输出(Maybe Integer
的列表)并且惊讶地发现它返回整数列表(sans Just
)而不是它们的总和。所以在上面的解决方案中,我第二次应用 sum
来实际获得总和。
我想从概念上理解为什么会这样:换句话说,为什么 sum
在这种情况下表现得像一个从 Maybe Ints 到 Ints 的转换器,而不是添加东西?
我已经解决了一些依赖辅助函数的类似练习,以避免对 Maybe
值进行计算的复杂性,也许在这种情况下我应该只计算 total
不使用 square
,即:
total = sum [2^n | n <- [0..63]]
然而,由于我已经编写了一个有用的函数,所以我的第一直觉是重用它,这导致了一些无法预料的行为。
最佳答案
让我们看一下sum
的类型:
sum :: (Foldable t, Num a) => t a -> a
通常,对于初学者来说,这可以通过假设 t ~ []
来简化,因此我们改为使用 sum
作为
sum :: Num a => [a] -> a
如果我们尝试在您的示例中的这种类型上使用 sum
,我们将收到类型错误,因为您有一个 Maybe 数字列表,而不是数字列表。相反,您编写 fmap sum [Just 1]
,将 sum
和 fmap
特化为:
sum :: Maybe Integer -> Integer
fmap :: (Maybe Integer -> Integer) -> [Maybe Integer] -> [Integer]
所以问题实际上不是“为什么 sum
不添加东西”,而是“当给定一个 Maybe 时,sum
如何有一个有意义的定义整数?”
如果您不熟悉如何将 sum
解释为 Foldable
或 Maybe
是如何工作的,这是回答该问题的一种方法可折叠,只是尝试自己实现它。实际上只有一种合理的实现方式:
sum :: Maybe Integer -> Integer
sum Nothing = 0
sum (Just x) = x
对吧?有人问你“这里的数字总数是多少”,然后给了你 0 个或 1 个数字。很容易加起来。这正是 sum
为 Maybe 工作的方式,除了它通过 Foldable 而不是专用于 Maybe。
在此之后,当然很简单:您已经将您的 [Maybe Integer]
变成了 [Integer]
,当然还有 sum
ming 让您得到非 Nothing
条目的总和。
关于haskell - 为什么我必须调用 `sum` 两次来对 `Maybe Integer` 的列表求和?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68886619/
我有一个使用 HsOpenSsl 的 readPrivateKey 函数读取 Rsa key 的函数,不幸的是,我的函数的签名是这个 String -> IO (Maybe (IO Maybe Rsa
我有一个类型 data Foo = Foo { bar :: Bar, baz :: Baz } 我正在尝试解析文件以构造 Foo .我有函数可以尝试解析 Bar和 Baz成员(member) par
我有一个可能的列表和一个给我节点颜色的函数(如果存在): maybeNeighbors :: [Maybe Node] nodeColor :: Node -> Maybe Color 现在
我有一个可能的列表和一个给我节点颜色的函数(如果存在): maybeNeighbors :: [Maybe Node] nodeColor :: Node -> Maybe Color 现在
我想有一个类型的函数: f :: [Maybe a] -> Maybe [a] 例如 f [Just 3, Just 5] == Just [3, 5] f [Just 3, Nothing] ==
我刚开始学习 Haskell,我发现自己正在为家庭作业编写这段代码: eval :: ExprT -> Integer eval (Lit x) = x eval (Add x y) = (e
我有一个类型为 Integral => a -> a -> Maybe a 的函数 f。这意味着 f 1 2 是有效的代码,但是自然的组合,例如 f (f 3 4) 5 f 6 (f 7 8) f (
我刚开始学习 Haskell,我发现自己正在为家庭作业编写这段代码: eval :: ExprT -> Integer eval (Lit x) = x eval (Add x y) = (e
是否可以轻松(无需重新发明轮子)从 (Maybe a, b) 转换至 Maybe (a,b) .我看了Traversable但不能让它工作。 最佳答案 您也可以使用 Bitraversable : b
我正在处理一个库( ghcjs-dom ),其中每个函数都返回一个 IO (Maybe T) . 我有一个函数a with 返回 IO (Maybe x)和功能 b需要x作为参数并返回 IO (May
我想计算列表的两个 elemIndex 值的差值。 colours = ["blue", "red", "green", "yellow"] ib = elemIndex "blue" colours
有一个标准tryPick如果 F# 返回第一个(从左到右,如果有的话)函数在列表元素上成功应用的函数。我希望在 Haskell 中有一个像这样的标准函数。我 tried胡歌,没有找到任何东西。 我是
我想将 Gen (Maybe Int) 转换为 Maybe Int。我有一个生成 1 到 9 之间的随机 Just Int 的函数。我想使用单元格函数,但我无法更改其类型签名中的任何内容。有什么建议吗
我想将以下回调代码包装到 Maybe public class FooDataSource ... public Maybe get(){ return Maybe.create(emitte
我想将 Gen (Maybe Int) 转换为 Maybe Int。我有一个生成 1 到 9 之间的随机 Just Int 的函数。我想使用单元格函数,但我无法更改其类型签名中的任何内容。有什么建议吗
这可能是一件简单的事情,但我正在编写一个想要返回记录的函数,并且其中几个字段需要执行可能失败的操作,所以现在结果记录看起来像这样(假设它是类型别名为 MyRecord)。 { field1 : May
为什么流程会在这里抛出错误? type MaybeProp = { prop: ?number, } type DefinetlyProp = { prop: number, } const
我想建立一个 Repository返回 Single 的类. 该类应首先查看 Cache返回 Maybe如果 Maybe完成转到我的Service返回 Single interface Cache {
使用 Typescipt 4.x.x 我写了一些代码来实现其他语言 Elm/Rust/Haskell 中常用的 Maybe/Option 类型。 我想写一个可以接受映射类型的通用函数 type MyM
在 Elm 中,将 List (Maybe a) 转换为 Maybe (List a) 的好方法是什么? 逻辑很简单: 如果所有项都是Just a,则返回Just (List a) 否则,返回Noth
我是一名优秀的程序员,十分优秀!