liftM和mapM有什么区别?
我试图弄清楚库函数groupBy(来自Data.List)的行为,它声称通过作为第一个参数传入的"相等测试"函数对列表的元素进行分组.类型签名表明,相等性测试只需要具有类型
(a -> a -> Bool)
Run Code Online (Sandbox Code Playgroud)
但是,当我在GHCi 6.6中使用(<)作为"相等测试"时,结果不是我所期望的:
ghci> groupBy (<) [1, 2, 3, 2, 4, 1, 5, 9]
[[1,2,3,2,4],[1,5,9]]
Run Code Online (Sandbox Code Playgroud)
相反,我希望运行严格增加的数字,如下所示:
[[1,2,3],[2,4],[1,5,9]]
Run Code Online (Sandbox Code Playgroud)
我错过了什么?
我最近一直在接受F#(我的背景是C#)并且正在阅读http://fsharpforfunandprofit.com网站,我发现这非常有帮助.
我必须http://fsharpforfunandprofit.com/posts/defining-functions/这是关于组合器的部分.除了红隼之外,我全都了解它们(虽然Y组合器或Sage鸟用我的脑子拧!).Scott Wlaschin将定义(在F#中)定义为:
let K x y = x
Run Code Online (Sandbox Code Playgroud)
对于我的生活,我无法理解任何有用的情况.起初我认为它可能被用作链式运算符,因此您可以将值传递给函数,然后返回原始值.我以前自己写过这样一个算子,但你可以看到它不一样:
let (>|) x f = f x; x
Run Code Online (Sandbox Code Playgroud)
如果我们部分应用K组合子(值为5),那么我们返回一个忽略其参数的函数,而是返回5.再次,没有用.
(K 5) = fun y -> 5
Run Code Online (Sandbox Code Playgroud)
任何人都可以给我一个简单的例子,说明这可能会被使用吗?
例如,给出以下树数据类型:
data Tree a = Node [Tree a] | Leaf a deriving Show
type Sexp = Tree String
Run Code Online (Sandbox Code Playgroud)
如何使用高阶组合器表达"漂亮"功能,该组合打印出适当缩进的树?例如:
sexp =
Node [
Leaf "aaa",
Leaf "bbb",
Node [
Leaf "ccc",
Leaf "ddd",
Node [
Leaf "eee",
Leaf "fff"],
Leaf "ggg",
Leaf "hhh"],
Leaf "jjj",
Leaf "kkk"]
pretty = ????
main = print $ pretty sexp
Run Code Online (Sandbox Code Playgroud)
我希望该程序的结果是:
(aaa
bbb
(ccc
ddd
(eee
fff)
ggg
hhh)
jjj
kkk)
Run Code Online (Sandbox Code Playgroud)
这是一个不完整的解决方案,使用"fold"作为组合器,不实现缩进:
fold f g (Node children) = f (map (fold f g) children) …Run Code Online (Sandbox Code Playgroud) 编辑:我在写这篇文章的过程中发现了我自己问题的部分答案,但我认为它很容易改进,所以无论如何我都会发布它.也许那里有更好的解决方案?
我正在寻找一种简单的方法来定义let表单中的递归函数而不诉诸letfn.这可能是一个不合理的请求,但我寻找这种技术的原因是因为我混合了数据和递归函数,这些函数在某种程度上相互依赖需要大量的嵌套let和letfn语句.
我想编写生成这样的惰性序列的递归函数(以Fibonacci序列为例):
(let [fibs (lazy-cat [0 1] (map + fibs (rest fibs)))]
(take 10 fibs))
Run Code Online (Sandbox Code Playgroud)
但似乎在clojure中,fibs在绑定期间不能使用它自己的符号.显而易见的是使用它letfn
(letfn [(fibo [] (lazy-cat [0 1] (map + (fibo) (rest (fibo)))))]
(take 10 (fibo)))
Run Code Online (Sandbox Code Playgroud)
但正如我刚才所说,这导致了很多繁琐的嵌套和交替的let和letfn.
为了在没有letfn和使用的情况下做到这一点let,我开始编写一些使用我认为的U-combinator的东西(刚刚听说过这个概念):
(let [fibs (fn [fi] (lazy-cat [0 1] (map + (fi fi) (rest (fi fi)))))]
(take 10 (fibs fibs)))
Run Code Online (Sandbox Code Playgroud)
但如何摆脱冗余(fi fi)呢?
正是在这一点上,经过一个小时的挣扎并逐渐向组合子Q添加位,我发现了自己问题的答案.
(let [Q (fn [r] …Run Code Online (Sandbox Code Playgroud) 在这种情况下,我仍然无法解决lambda的工作原理.
foldr (\y ys -> ys ++ [y]) [] [1,2,3]
Run Code Online (Sandbox Code Playgroud)
有人可以一步一步地试着向我解释一下吗?
而且如何foldl工作?
是否有一个固定点组合器用于创建相互递归函数的元组?即我正在寻找像Y-Combinator这样的东西,但它需要多个"递归"*函数,并将返回一个函数元组?
*:当然不是真正的递归,因为它们是以通常的Y-Combinator方式将自己(和兄弟姐妹)作为参数编写的.
recursion functional-programming combinators y-combinator mutual-recursion
我最近使用Ply在Python中编写了一个解析器(它是yacc的python重新实现).当我差不多完成解析器时,我发现我需要解析的语法要求我在解析过程中进行一些查找以通知词法分析器.在没有查看通知词法分析器的情况下,我无法正确解析语言中的字符串.
鉴于我可以从语法规则控制词法分析器的状态,我想我将使用解析器模块中的查找表来解决我的用例,但是维护/测试可能变得太难了.所以我想了解一些其他选择.
在Haskell中,我会使用Parsec,一个解析函数库(称为组合器).是否有Parsec的Python实现?或者也许其他一些生产质量库充满了解析功能,所以我可以在Python中构建一个上下文敏感的解析器?
编辑:我在上下文免费解析的所有尝试都失败了.出于这个原因,我不认为ANTLR在这里有用.
在编写简单的RPN计算器的过程中,我有以下类型的别名:
type Stack = List[Double]
type Operation = Stack => Option[Stack]
Run Code Online (Sandbox Code Playgroud)
...我写了一个好奇的Scala代码:
val newStack = operations.foldLeft(Option(stack)) { _ flatMap _ }
Run Code Online (Sandbox Code Playgroud)
这将获取stack值的初始值并应用operations该堆栈的列表.每个操作都可能失败(即产生一个Option[Stack]),所以我对它们进行排序flatMap.对我来说有些不同寻常的事情(在我看来)是我折叠了一系列monadic函数,而不是折叠数据列表.
我想知道是否有一个标准函数可以捕获这种"折叠绑定"行为.当我试图玩"Name That Combinator"游戏时,Hoogle通常是我的朋友,所以我在Haskell尝试了相同的心理锻炼:
foldl (>>=) (Just stack) operations
Run Code Online (Sandbox Code Playgroud)
这里的类型是:
foldl :: (a -> b -> a) -> a -> [b] -> a
(>>=) :: Monad m => m a -> (a -> m b) -> m b
Run Code Online (Sandbox Code Playgroud)
所以我的神秘foldl (>>=)组合器的类型,在制作类型foldl和(>>=)排队之后,应该是:
mysteryCombinator :: Monad m => …Run Code Online (Sandbox Code Playgroud) 在Real World Haskell中,他们描述了这样的组合器:
在Haskell中,我们引用将其他函数作为参数并将新函数作为组合器返回的函数.
然后他们声明该maybeIO函数是一个组合器,它的类型签名如下所示:
maybeIO :: IO a -> IO (Maybe a)
Run Code Online (Sandbox Code Playgroud)
但我只能看到这maybeIO是一个函数,它接受IO monad中包含的值并返回IO monad中的值.那么这个函数如何成为组合子呢?