使用Maybe

时间:2017-12-26 23:03:55

标签: haskell recursion immutability

我很难尝试使用递归来编写函数来查找两个列表的总和,如果任何列表为空,则可能是Nothing。

以下函数的数学运算是:

Σw[i]x[i]

其中w和x是等长的int数组

这是我的工作代码:

example :: [Int] -> [Int] -> Int
example [] [] = 0
example (x:xs) (l:ls) = ((x*l) + (example xs ls))

以下是我想要工作的想法:

example :: [Int] -> [Int] -> Maybe Int
example [] [] = Nothing
example (x:xs) (l:ls) = Just((x*l) + (example xs ls))

由于

2 个答案:

答案 0 :(得分:5)

我猜你的意图是什么,不确定我是否正确阅读:当两个输入列表的长度不同时,你希望函数产生Nothing吗?

"快乐"基本情况为0,就像第一次尝试一样,但被提升到Maybe

example [] [] = Just 0

要处理列表长度不同的情况,请包括只有一个列表为空的情况。如果不包括这些情况,您应该收到关于非详尽模式匹配的编译器警告。

example [] _ = Nothing
example _ [] = Nothing

最后一个案例是你有两个非空列表。它看起来很像你第一次尝试的那一行,除了直接将加法应用于example xs ys,我们 fmap 加上example xs ys,事实MaybeFunctor

example (x : xs) (y : ys) = fmap (x * y +) (example xs ys)

使用示例:

λ> example [1,2] [3,4]
Just 11

λ> example [1,2] [3,4,5]
Nothing

顺便说一句,如果您想使用这个库,safe将是一个很好的选择,将其变成一个单行。

import Safe.Exact

example xs ys = fmap sum (zipWithExactMay (*) xs ys)

答案 1 :(得分:1)

即将结束,但您对from lxml import html import requests SEC_pageA = requests.get('https://www.sec.gov/Archives/edgar/data/1000228/000100022810000006/the10k_2009.htm') SEC_treeA = html.fromstring(SEC_pageA.content) SalesA = SEC_treeA.xpath('(//p[contains(., "CONSOLIDATED STATEMENTS OF INCOME")]/following::td[contains(.,"Net sales")]/following-sibling::td[@align="right"]//text())[1]') SEC_pageB = requests.get('https://www.sec.gov/Archives/edgar/data/320193/000119312515356351/d17062d10k.htm') SEC_treeB = html.fromstring(SEC_pageB.content) SalesB = SEC_treeB.xpath('(//p[contains(., "CONSOLIDATED STATEMENTS OF OPERATIONS")]/following::td[contains(.,"Net sales")]/following-sibling::td[@align="right"]//text())[1]') print SalesA print SalesB 的递归调用会返回example xs ls,而您无法添加Maybe IntInt({{1} }}),因此你在最后一行的错误。

您可以使用fromMaybe来处理此案例,并使用Maybe Int作为默认总和:

x*l + example xs ls

或者(更整洁地),您可以使用以下内容避免显式递归:

0

请注意,模式匹配中有非穷举模式。两个不同长度的列表将导致模式匹配异常。