我正在做Cay Horstmann的组合器解析器练习,我想知道区分表示数字的字符串和表示匹配语句中的变量的字符串的最佳方法:
def factor: Parser[ExprTree] = (wholeNumber | "(" ~ expr ~ ")" | ident) ^^ {
case a: wholeNumber => Number(a.toInt)
case a: String => Variable(a)
}
Run Code Online (Sandbox Code Playgroud)
那里的第二行,"案例a:整数"不合法.我想到了一个正则表达式,但还没有找到一种方法让它与"案例"一起工作.
不经常,人们希望<=>在产品数据类型上实现(比较或"太空船")运算符,即具有多个字段的类(所有这些(我们希望!)已经<=>实现),比较某些字段订购.
def <=>(o)
f1 < o.f1 && (return -1)
f1 > o.f1 && (return 1)
f2 < o.f2 && (return -1)
f2 > o.f2 && (return 1)
return 0
end
Run Code Online (Sandbox Code Playgroud)
这既繁琐又容易出错,尤其是在很多领域.它容易出错,我经常觉得我应该对这个功能进行单元测试,这只会增加乏味和冗长.
Haskell提供了一种特别好的方法:
import Data.Monoid (mappend)
import Data.Ord (comparing)
-- From the standard library:
-- data Ordering = LT | EQ | GT
data D = D { f3 :: Int, f2 :: Double, f1 :: Char } deriving Show
compareD :: D -> D -> Ordering … 我正在摆弄JavaScript中的Cominators,当我偶然发现维基百科说:"Y组合子可以在SKI演算中表达为:Y = S(K(SII))时,我很自豪(希望)让S上班." S(S(KS)K)(K(SII)))",所以我必须尝试:
var I = function (x) {
return x;
};
var K = function (x) {
return function(){
return x;}
};
var S = function (x) {
return function (y) {
return function (z) {
return x(z)(y(z));
}
}
};
var Y = S (K(S(I)(I))) (S(S(K(S))(K)) (K(S(I)(I))));
Y; //evals to:
//function (z) {return x(z)(y(z));}
//And this (lifted from Crockford's Site):
var factorial = Y(function (fac) {
return function (n) {
return n <= 2 ? n : …Run Code Online (Sandbox Code Playgroud) 此函数f接受参数列表并返回具有相同参数列表的另一个callable,以便可以对其应用其他函数.
from operator import add, mul
def f(*a, **kw):
return lambda g: g(*a, **kw)
map(f(3, 10), (add, mul)) # -> [13, 30]
Run Code Online (Sandbox Code Playgroud)
你叫f什么?这是某种组合器吗?
我刚刚发现了以下lambda演算表达式:
(((? f . (? x . (f x))) (? a . a)) (? b . b))
Run Code Online (Sandbox Code Playgroud)
所以这是一个函数,它接受一个参数f并返回另一个带有参数x的函数,并产生应用于f的x的结果.上述表达式的结果将是(λb.b).
这让我想起部分应用和currying,但是"由内而外"的功能应用程序(fx)引起了我的兴趣.
那个表达有更深刻的理论意义吗?
lambda functional-programming combinators lambda-calculus higher-order-functions
假设我有两个函数f :: [a] -> b和g :: [a] -> c.我有以下两个问题:
如果我执行(f &&& g) xs,其中xs :: [a],如果都f和g涉及循环,有可能是编译器这两个循环优化成一个?(请注意,我不是在问一些特定的Haskell编译器是否实现了这一点.我想知道这样的事情是否可行.)
类型类中的traverse函数可以Traverse帮助我进行这样的优化,包括以下几行:
traverse (someCombinator f g) xs
Run Code Online (Sandbox Code Playgroud)在搜索关于Raymond Smullyan的To Mock a Mockingbird的信息时,我偶然发现了Stephen Tetley的基本组合器的Haskell代码.我认为这是一个有趣的想法,并决定使用这些组合器从To Mock a Mockingbird的第24章实施"可以做算术的鸟".我得到了定义真理,虚假,继承者,前任和零检查组合的功能,以及将组合布尔变为Haskell布尔值的功能,反之亦然.但是当我尝试创建一个带有组合数并返回整数的函数时,我会遇到问题.我想知道如何使这个功能工作.这是我到目前为止所得到的:
-- | The first 7 combinators below are from Stephen Tetley's Data.Aviary.Birds
-- | (http://hackage.haskell.org/package/data-aviary-0.2.3/docs/Data-Aviary-Birds.html),
-- | with minor modifications.
-- | S combinator - starling.
-- Haskell: Applicative\'s @(\<*\>)@ on functions.
-- Not interdefined.
st :: (a -> b -> c) -> (a -> b) -> a -> c
st f g x = f x (g x)
-- | K combinator …Run Code Online (Sandbox Code Playgroud) 我想写一个Haskell函数,它返回一个附加到自身计数次数的列表(比如lst * count在Python中).
我的第一次尝试是:
self_append_n :: Int -> [a] -> [a]
self_append_n = concat . replicate
Run Code Online (Sandbox Code Playgroud)
我的理由是replicate接受一个计数和一个值,并产生一个值列表.当值本身就是一个列表时,剩下的就是将列表连接在一起.但是,这给出了一个令人困惑的错误:
Couldn't match type `[a0]' with `[a] -> [a]'
Expected type: [[a0]] -> [a] -> [a]
Actual type: [[a0]] -> [a0]
In the first argument of `(.)', namely `concat'
In the expression: concat . replicate
In an equation for `self_append_n':
self_append_n = concat . replicate
Run Code Online (Sandbox Code Playgroud)
然后我写了一个有点版本:
self_append_n a b = concat $ replicate a b
Run Code Online (Sandbox Code Playgroud)
它的工作原理!
为什么无点编译无法编译,但添加点可以使它工作?
在Edward Kmett的演讲中,Lenses,Folds和Traversals,在幻灯片"The Power is the Dot"中,他展示的(.) . (.) . (.)是
(a -> b) -> (c -> d -> e -> a) -> c -> d -> e -> b
我可以通过在GHCI中显示它的类型来看到它.但我也想知道原因.我想了解的另一件事是为什么有在从参数中经常换着花样(.)来(.) . (.)和(.) . (.) . (.):
(.) :: (a -> b) -> (c -> a) -> c -> b
(.) . (.) :: (a -> b) -> (c -> d -> a) -> c -> d -> b
(.) . …Run Code Online (Sandbox Code Playgroud) haskell types type-inference combinators function-composition
我是haskell的初学者,并试图实现自然数字的Church编码,如本指南中所述.我从这个答案中使用了y组合器的定义,但不确定如何应用它.
我想实现在演算一个简单的功能,computues的[1..1]作为证明的总和这里.
{-# LANGUAGE RankNTypes #-}
import Unsafe.Coerce
y :: (a -> a) -> a
y = \f -> (\x -> f (unsafeCoerce x x)) (\x -> f (unsafeCoerce x x))
true = (\x y -> x)
false = (\x y -> y)
newtype Chur = Chr (forall a. (a -> a) -> (a -> a))
zer :: Chur
zer = Chr (\x y -> y)
suc :: Chur -> Chur
suc (Chr cn) …Run Code Online (Sandbox Code Playgroud) combinators ×10
haskell ×5
types ×2
function ×1
javascript ×1
lambda ×1
parsing ×1
pointfree ×1
python ×1
ruby ×1
scala ×1
y-combinator ×1