gpt4 book ai didi

haskell - SYB : can a map over the result of listify be rewritten with a gfoldl?

转载 作者:行者123 更新时间:2023-12-01 12:36:26 27 4
gpt4 key购买 nike

我可以用SYB的gfoldl一次性对listify的结果进行映射吗?

例如考虑以下代码:

extractNums :: Expr -> [Int]
extractNums e = map numVal $ listify isNum e

where isNum :: Expr -> Bool
isNum (Num _) = True
isNum _ = False

numVal :: Expr -> Int
numVal (Num i) = i
numVal _ = error "Somehow filter did not work?"

我不喜欢在 numVal 函数中我必须考虑 Expr 类型的不同数据构造函数,而我只对 Num 构造函数感兴趣。我宁愿用下面的 vals 函数替换 isNum 和 numVals:

    vals :: [Int] -> Expr -> [Int]
vals xs (Num x) = x : xs
vals xs _ = xs

这可以用 gfoldl 完成吗?怎么办?

最佳答案

函数 listify 定义为

-- | Get a list of all entities that meet a predicate
listify :: Typeable r => (r -> Bool) -> GenericQ [r]
listify p = everything (++) ([] `mkQ` (\x -> if p x then [x] else []))

类似于过滤器。我们可以创建一个类似于 mapMaybe 的替代方案,它将您需要的 mapfilter 合二为一:

import Data.Generics
import Data.Generics.Schemes
import Data.Maybe (maybeToList)
import Data.Typeable

listify' :: (Typeable t) => (t -> Maybe r) -> GenericQ [r]
listify' f = everything (++) ([] `mkQ` (maybeToList . f))

那么你的例子可以表示为

numVal :: Expr -> Maybe Int
numVal (Num i) = Just i
numVal _ = Nothing

test :: Expr -> [Int]
test = listify' numVal

关于haskell - SYB : can a map over the result of listify be rewritten with a gfoldl?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29298106/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com