我试图写一个线性插值在Haskell:
linear_interpolation:: [(Double, Double)] -> Double -> Maybe Double
linear_interpolation list x
| x1 /= Nothing && x2 /= Nothing && y1 /= Nothing && y2 /= Nothing
= Just (y1+ (y2-y1)*(x - x1)/(x2 - x1))
| otherwise = Nothing
where
x2 = find (> x) (x_list list)
x1 = max_elem $ filter (< x) (x_list list)
y1 = lookup x1 list
y2 = lookup x2 list
但我得到这个错误:
• Couldn't match type ‘Double’ with ‘Maybe Double’
Expected: [(Maybe Double, Double)]
Actual: [(Double, Double)]
• In the second argument of ‘lookup’, namely ‘list’
In the expression: lookup x2 list
In an equation for ‘y2’: y2 = lookup x2 list
|
29 | y2 = lookup x2 list
| ^^^^
我真的不明白是怎么回事,因为查找类型是这样的:
lookup :: Eq a => a -> [(a, b)] -> Maybe b
附言
对于y1,x1,x2也有同样的问题
1条答案
按热度按时间c86crjj01#
测试
x1 /= Nothing
不会改变x1
的类型,它仍然是Maybe Double
,所以我们不能在x1
上执行算术运算。因此,测试
x1 /= Nothing
、isNothing x1
或isJust x1
很可能是错误的。通常我们真正需要使用的是 * 模式匹配 *:这里,
x1',x2',y1',y2'
将具有所需的类型Double
。嵌套的
let
和case
不是那么可读,在这种情况下,如果我们利用Maybe
单子并使用do
表示法会更简单。这里,我们使用
<-
,使x1,x2,y1,y2 :: Double
从类型中删除Maybe
,Nothing
的情况会自动处理,这使得它非常方便。