我正在尝试实现一个惰性序列(意味着下一个项目仅在您调用步骤函数时计算),其中一个方法应该是"map",它接收一个影响所有成员的函数.最优雅的方法是使用函数组合,并将新函数分配给函数变量,但由于函数不是Java中的第一类值,我不知道如何执行此操作.
我想过有一个只包含一个函数的类,作为一个"函数指针"包装器,但我不知道它是如何用于组合的.
编辑:问题是与家庭作业有关.此外,它应该能够沿着地图线处理多个合成(map(map(stepFunction())))(在这种情况下,"map"是通过方法"map"给出的函数).
我对Haskell相对较新,如果我的问题听起来很愚蠢,那么道歉.我一直试图理解功能组合是如何工作的,我遇到了一个问题,我想知道有人可以帮助我.我在以下两个场景中使用函数组合中的map:
map (*2) . filter even [1,2,3,4]map (*2) . zipWith max [1,2] [4,5]虽然filter和zipWith函数都返回一个列表,但只有第一个组合有效,而第二个组合会抛出以下错误:
"Couldn't match expected type '[Int] -> [Int]' with actual type '[c0]'
Run Code Online (Sandbox Code Playgroud)
任何建议将不胜感激.
回想一下,K组合器是一个常数函数.它总是返回它的第一个参数:
Kxy = x for all y
Run Code Online (Sandbox Code Playgroud)
在To Mock a Mockingbird这本书中,作者提供了一个含有说话鸟类的魔法森林的例子.这些鸟有行为:
鉴于任何鸟类A和B,如果您将B的名称称为A,那么A将通过向您呼叫某只鸟的名称来回应:这只鸟我们将由AB指定.
假设森林由三只鸟A,B和C组成.至少有一只鸟可能像K组合一样吗?
下面的表格显示了魔法森林中鸟类的一组可能行为.第一列包含森林中每只鸟的名称.顶行的名称可以调用每只鸟.身体是鸟对名字的反应.例如,如果您将A的名称称为鸟A,则鸟A将以C响应(请参阅第2行第2列).简洁地说,AA = C.如果你把B的名字叫做鸟A,那么鸟A会回答B(见第2行,第3栏).简洁地说,AB = B. AC的空槽应该有什么值?
| A B C
------------------
A | C B
B | B B B
C | A A A
Run Code Online (Sandbox Code Playgroud)
让我们看看我们是否可以让鸟A表现得像K组合器.上面的一组值看起来很有希望:
对于所有y,AA = C且Cy = A. 也就是说,对于所有y,(AA)y = A.
对于所有y,AB = B且By = B. 也就是说,对于所有y,(AB)y = B.
空槽(AC)应该放置什么值?考虑所有情况:
如果AC = A则所有y的Ay值必须为C,这显然是错误的.因此,A不能是空槽的正确值.
如果AC = B则所有y的By值必须为C,这显然是假的.因此,B不能是空槽的正确值.
如果AC = C则所有y的Cy值必须为C,这显然是假的.因此,C不能是空槽的正确值.
因此,对于每个y,不能在空槽中放置值以满足条件(AC)y = C.
据我所知,不可能让任何一只鸟表现得像K组合器.我希望你能证明我错了.
lambda functional-programming combinators function-composition k-combinator
所以,让我们直截了当.
:t (map.foldr)
(map.foldr) :: (a1 -> a -> a) -> [a] -> [[a1] -> a]
Run Code Online (Sandbox Code Playgroud)
什么是[[a1] - > a]?我真的想要理解这个构图,所以我这样做:
-- map.foldr
map.foldr :: (a1 -> a -> a) -> [a] -> [[a1] -> a]
map :: (a1 -> b1) -> [a1] -> [b1]
(.) :: (y -> w) -> (x -> y) -> x -> w
foldr :: (a -> b -> b) -> b -> [a] -> b
y = (a1 -> b1) w = ([a1] -> [b1]) …Run Code Online (Sandbox Code Playgroud) 对 Erlang 来说是全新的。我试图定义函数组合一些功能,比如compose,juxt和pipe而运行到一个事实,即二郎神没有(据我所知)可变参数所以这是很难写只是一个版本的这种功能,将所有输入工作.
到目前为止,我最好的想法是将不同数量的函数硬编码到一个合理的数字,并提供一个版本,该版本采用更大的列表,如下所示:
pipe (X, Fs) when is_list(Fs) -> lists:foldl(fun (F, Acc) -> F(Acc) end, X, Fs);
pipe (X, F) -> F(X).
pipe (X, F, G) -> G(F(X)).
pipe (X, F, G, H) -> H(G(F(X))).
pipe (X, F, G, H, I) -> I(H(G(F(X)))).
pipe (X, F, G, H, I, J) -> J(I(H(G(F(X))))).
pipe (X, F, G, H, I, J, K) -> K(J(I(H(G(F(X)))))).
pipe (X, F, G, H, I, J, K, L) -> L(K(J(I(H(G(F(X))))))). …Run Code Online (Sandbox Code Playgroud) (这是来自Typeclassopedia的练习.)
如何计算两个非平凡函数的组合类型,如foldMap . foldMap?
对于简单的情况,这很简单:只需看看它的类型 (.)
(.) :: (b -> c) -> (a -> b) -> (a -> c)
Run Code Online (Sandbox Code Playgroud)
并找到类型a,b并c为两个功能.
在这种情况下foldMap,类型是
foldMap :: (Foldable t, Monoid m) => (a -> m) -> t a -> m
Run Code Online (Sandbox Code Playgroud)
我认为无法将此功能的类型"拆分"为两部分,因此我可以获得"a","b"和"c"类型(.).
然后我要求ghci计算它的类型.它成功了以下类型:
Prelude Data.Foldable> :t foldMap . foldMap
foldMap . foldMap
:: (Foldable t, Foldable t1, Data.Monoid.Monoid m) =>
(a -> m) -> t (t1 a) -> m …Run Code Online (Sandbox Code Playgroud) 我喜欢柯里化,但有几个 Javascript 开发人员拒绝这种技术的原因有几个:
f(x) (y) (z)有没有一种方法可以减轻这些担忧,这样我的同事就不会讨厌我?
javascript functional-programming currying function-composition higher-order-functions
我有一个Play框架应用程序和一个有问题的操作。我试图使用解析一个请求正文parse.form,然后ActionFilter对该解析的正文进行运行。
到目前为止,我有这样的事情
object ModelValidationAction extends ActionFilter[Request[MyModel]]{
def filter[A <: MyModel](request: Request[A]) = ???
}
def routePointsHere = (Action(parse.form(myModelForm)) andThen ModelValidationAction) { (request: Request[MyModel]) => ??? }
Run Code Online (Sandbox Code Playgroud)
但是IDEA给我错误提示
预期的Action [MyModel] => NotInferredA,实际的ModelValidationAction.type
编译器告诉我
...在特征ActionBuilder中应用的方法缺少参数列表
[错误]仅当需要函数类型时,才会将未应用的方法转换为函数。[错误]您可以通过写入apply _或apply(_)(_)代替来明确显示此转换apply。
因此,我可以了解到问题是apply[A](bodyParser: BodyParser[A])(block: R[A] => Result): Action[A]围绕第二个参数列表未填充的方法,但是我不知道该语言在这里的行为。
我的(完全没有根据的)的假设是,Action(parse.form(myModelForm))将成为Request[MyModel] => Result和调用andThen将返回相同的。
关于我所缺少的任何指针?谢谢!
scala function function-composition playframework playframework-2.0
我真的很喜欢Python生成器。特别是,我发现它们只是连接到Rest端点的正确工具-我的客户端代码只需要在连接该端点的生成器上进行迭代。但是,我发现Python生成器的表现力不如我所愿。通常,我需要过滤从端点获取的数据。在当前代码中,我将谓词函数传递给生成器,并且将谓词应用于要处理的数据,并且仅在谓词为True时才产生数据。
我想转向生成器的组成-如data_filter(datasource())。这是一些演示代码,显示了我尝试过的内容。很清楚为什么它不起作用,我试图弄清楚的是达到解决方案的最富有表现力的方式:
# Mock of Rest Endpoint: In actual code, generator is
# connected to a Rest endpoint which returns dictionary(from JSON).
def mock_datasource ():
mock_data = ["sanctuary", "movement", "liberty", "seminar",
"formula","short-circuit", "generate", "comedy"]
for d in mock_data:
yield d
# Mock of a filter: simplification, in reality I am filtering on some
# aspect of the data, like data['type'] == "external"
def data_filter (d):
if len(d) < 8:
yield d
# First Try:
# for w in …Run Code Online (Sandbox Code Playgroud) 所以这个问题很简单,但我似乎无法理解这个概念。
要组成普通函数,可以执行以下操作:
lowerNoSpaces = filter (/= ' ') . map toLower
Run Code Online (Sandbox Code Playgroud)
但是,有时候,这有时行不通:
myConcatMap = concat . map
Run Code Online (Sandbox Code Playgroud)
它给出了错误:
<interactive>:236:1: error:
* Non type-variable argument
in the constraint: Foldable ((->) [a1])
(Use FlexibleContexts to permit this)
* When checking the inferred type
concattMap :: forall a1 a2.
Foldable ((->) [a1]) =>
(a1 -> a2) -> [a2]
Run Code Online (Sandbox Code Playgroud)
但是当相同的函数表示为:
myConcatMap = (concat .) . map
Run Code Online (Sandbox Code Playgroud)
它完全按预期工作。
我知道这是有原因的,但是我一直盯着它看了一阵子,但仍然不太明白为什么原版不起作用而本原版却起作用。
为什么会有两个“。” 的?