类型的“地图”
mapIsh :: Traversable t => (a -> Either b c) -> t a -> Either b (t c)
将是一个开始。 (Hayoo找不到一个。)或者是“ 最重要的是(对于我的情况)是这样的: 这可能是您需要阅读的全部内容。如果你想要更多细节,这里有一个具体的例子: 想象一下将阿克苏姆映射过的树状结构。每个分支在评估其子代后,都会通过其子代和累加器的某些功能进行转换。 这里有一些工作代码,可以将每个Tree的值添加到累加器中,还可以为每个Branch的标签添加其子标签的产品: 这是返回的内容: 但是,如果不使用foldl中的(*),我们使用了evenMult?foldIsh :: (b -> a -> Either l b) -> b -> t a -> Either l b
mapAccumIsh :: (a -> b -> Either l (a, c)) -> a -> t b -> Either l (a, t c)
module Temp where
import Data.List
data Tree = Leaf Float | Branch Float [Tree] deriving (Show)
label :: Tree -> Float
label (Leaf i) = i
label (Branch i _) = i
f :: Float -> Tree -> (Float, Tree)
f i (Leaf j) = (i+j, Leaf j)
f i (Branch j ts) = (i + tf, Branch tf ts2) where
(i2, ts2) = mapAccumL f i ts
tf = j + (foldl (*) 1 $ map label ts2)
-- the problem: what if instead of (*) in the line above, we used this?
evenMult :: Float -> Float -> Either String Float
evenMult a b = case even $ round b of True -> Right $ a * b
False -> Left "that's odd"
go = f 0 $ Branch 2 [Branch 2 [Leaf 2]
,Branch 2 [Leaf 2, Leaf (-2)]]
(-6.0,Branch (-6.0) [Branch 4.0 [Leaf 2.0]
,Branch (-2.0) [Leaf 2.0,Leaf (-2.0)]])