haskell 有没有一种好的方法来解开元组中的Maybe值?

ryoqjall  于 2022-11-14  发布在  其他
关注(0)|答案(2)|浏览(194)

我需要的签名是(Maybe a, b) -> (a, b),hoogle返回no results

import Data.Maybe (fromJust)

fromJustTuple :: (Maybe a, b) -> (a, b)
fromJustTuple (a, b) = (fromJust a, b)

上下文是,我在Map上使用updateLookupWithKey,我可以保证我查询的键存在。

let (Just x, myMap') = updateLookupWithKey f k myMap

,但这样我就不得不禁用incomplete-uni-patterns,这是我不想做的。
退一步说,这可能是一个XY problem。我很高兴听到这样的消息,并了解到一个不同的,更惯用的方法。

ix0qys7i

ix0qys7i1#

把我自己的评论抄成一个答案:
您可以将fromJustTuple写为first fromJust(其中first来自Control.Arrow)。
first具有类型签名:

first :: Arrow a => a b c -> a (b, d) (c, d)

但是,忽略first的“箭头”部分,并假定它专用于函数,这可能是有意义的,这使它具有以下类型:

first :: (b -> c) -> (b, d) -> (c, d)

也就是说:它Map到元组的第一个元素上。
最后,我认为您的问题在于,虽然您“可以保证[您]查询的键存在”,但您无法向类型系统证明这一点,因此除非您可以更改这一点,否则您将不得不依赖fromJust这样的不安全函数,或者收到不完整模式匹配警告。

envsm3lx

envsm3lx2#

我认为困难的原因是updateLookupWithKey只是不是合适的工具,为什么不使用alterF呢?

import Data.Map (Map)
import qualified Data.Map as M

import Data.Maybe

update :: (Ord k, Num a) => (a -> a) -> k -> Map k a -> (a, Map k a)
update f = M.alterF (\old -> let new = f (fromMaybe 0 old) in (new, Just new))

incr :: (Ord k, Num a) => k -> Map k a -> (a, Map k a)
incr = update (+1)

decr :: (Ord k, Num a) => k -> Map k a -> (a, Map k a)
decr = update (subtract 1)

现在,Maybe的唯一外观是覆盖Map中实际上不存在该键的情况,并且在这种情况下,它将关联值默认为0。

相关问题