代数数据类型的"代数"表达式对于具有数学背景的人来说非常具有启发性.让我试着解释一下我的意思.
定义了基本类型
•+X1并使用简写X²的X•X和2X对X+X等等,我们就可以定义如链表代数表达式
data List a = Nil | Cons a (List a) ↔ L = 1 + X • L
和二叉树:
data Tree a = Nil | Branch a (Tree a) (Tree a) ↔ T = 1 + X • T²
现在,我作为数学家的第一直觉是坚持这些表达方式,并试图解决L和T.我可以通过重复替换来做到这一点,但似乎更容易滥用符号,并假装我可以随意重新排列.例如,对于链接列表:
L = 1 + X • L
(1 - X) • L = 1
L = 1 …
ocaml haskell functional-programming algebraic-data-types miranda
John Hughes 在他的文章" 为什么功能编程很重要 "中辩称,"懒惰评估可能是函数式程序员模块中最强大的模块化工具." 为此,他提供了一个这样的例子:
假设您有两个函数,"infiniteLoop"和"terminationCondition".您可以执行以下操作:
terminationCondition(infiniteLoop input)
Run Code Online (Sandbox Code Playgroud)
懒惰的评价,在休斯的话中"允许终止条件与循环体分离".这绝对是正确的,因为这里使用延迟评估的"terminationCondition"意味着可以在循环外定义这个条件 - 当terminationCondition停止请求数据时,infiniteLoop将停止执行.
但高阶函数不能达到如下相同的效果吗?
infiniteLoop(input, terminationCondition)
Run Code Online (Sandbox Code Playgroud)
懒惰评估如何提供高阶函数不提供的模块化?
haskell functional-programming lazy-evaluation higher-order-functions miranda
简介: 这是Miranda考试的过去考试问题,但语法与Haskell非常相似.
问题: 以下表达式的类型是什么?它的作用是什么?(函数长度和交换的定义如下).
(foldr (+) 0) . (foldr ((:) . length . (swap (:) [] )) [])
length [] = 0
length (x:xs) = 1 + length xs
swap f x y = f y x
Run Code Online (Sandbox Code Playgroud)
注意:
请随时回复haskell语法 - 抱歉使用星形作为多边形,但我不想将它错误地翻译成haskell.基本上,如果一个变量的类型为*而另一个变量具有*,则表示它们可以是任何类型,但它们必须是同一类型.如果有**,则意味着它可以但不需要与*具有相同的类型.我认为它对应于haskell usuage中的a,b,c等.
我的工作到目前为止
从长度的定义中你可以看到它找到了任何列表的长度,所以这给出了
length :: [*] -> num.
Run Code Online (Sandbox Code Playgroud)
从定义我认为swap接受一个函数和两个参数,并产生交换的两个参数的函数,所以这给出
swap :: (* -> ** -> ***) -> ** -> [*] -> ***
Run Code Online (Sandbox Code Playgroud)
foldr使用二进制函数(如加号)作为起始值和列表,并使用该函数从右向左折叠列表.这给了
foldr :: (* -> ** -> **) -> ** -> [*] -> **)
Run Code Online (Sandbox Code Playgroud)
我知道在函数组合中它是正确的关联,所以例如第一个点(.)右边的所有内容都需要生成一个列表,因为它将作为第一个折叠器的参数给出.
foldr函数输出一个值(折叠列表的结果),所以我知道返回类型将是某种多义类型而不是多类型列表.
我的问题 …
给定以下函数定义并假设所有正整数的类似定义给出了一个名为plus的函数的类型定义和代码,它将把两个这样的函数作为参数表示整数并返回一个表示两个输入整数之和的函数.例如,(plus one two)应该评估一个带有两个参数f x并返回的函数(f(f(f x))).
one f x = f x
two f x = f (f x)
three f x = f (f (f x)))
Run Code Online (Sandbox Code Playgroud)
等等
我是函数式编程的新手,我无法理解这一点.我首先不知道如何定义所有正整数的函数而不将它们写出来(这显然是不可能的).如果我有plus(sixty, forty),我的功能怎么能识别六十次被应用60次x?
我打算在米兰达写这篇文章,但我对Haskell更熟悉,所以欢迎任何一方的帮助.
如何使用列表理解将列表分成两半?
如果我有[1,1,2,2,3,3,4,4,5,5] ,我只想要[1,1,2,2,3]
到目前为止我的尝试:
half mylist = [r | mylist!r ; r <- [0..(#mylist div 2)] ] ||does not work
Run Code Online (Sandbox Code Playgroud)
有什么想法吗?
[Nb:这实际上并不是Haskell,而是类似的.!用于索引列表,#给出长度)
编辑::
好的,事实证明
half mylist = [r | r <- [mylist!0..mylist!(#mylist div 2)] ]
Run Code Online (Sandbox Code Playgroud)
有效,但仅限于数字列表而非字符串.有线索吗?