8

我在 Haskell 中实现 FP (Backus) 解释器时遇到问题。

FP 函数如下所示:

[+,*]:<2,3>

应该导致

<+:<2,3>, *:<2,3>> ->
<5,6>

这意味着左侧列表中的每个函数都应该在右侧列表的每个元素上执行。

我的理解是,我需要类似于“map”函数的东西,但是 map 在列表中应用一个函数,并且我需要在值列表中使用函数列表。

先感谢您!:-)

编辑:

由于我不准确,这是我的代码不起作用:

apply :: [String] -> [Integer] -> [Integer]
apply fs v = [((apply_f f x) | f <- fs | x <- v)]

apply_f :: String -> [Integer] -> [Integer]
apply_f "+" v = [(sum v)]
apply_f "*" v = [(product v)]

我不知道为什么... :-(

编辑2:

对不起,我整天工作太累了。问题是我不需要第二个管道,只需要第一个:

apply fs v = [ apply_f f v | f <- fs ]

现在,一切正常,非常感谢!:-)

4

5 回答 5

18

我相信您正在寻找该zipWith功能并将其与 function application operator 一起应用$

所以,如果你有一个函数funcList列表和一个值列表,valueList你可以这样调用:

zipWith ($) funcList valueList

所以,使用它就像

zipWith ($) [(+ 5),(* 3)] [1,5]

给你结果[6,15]

要获得一种交叉应用程序,您可以使用

[f a | f <- [(+5), (*3)], a <- [1,5]]

这给了你[6,10,3,15]。不知道你所说的`<是什么意思,你想要对,嵌套列表还是你需要什么?

于 2012-08-25T17:21:13.350 回答
17

听起来你想要:

import Control.Applicative
apply :: [a -> b] -> [a] -> [b]
apply fs vals = fs <*> vals

当然,这与<*>为列表定义的实例相同。

于 2012-08-25T17:36:56.193 回答
6

你想要这样的东西吗?

[f x | f <- [(+3),(*2)], x <- [1..2]]

输出:

[4,5,2,4]

编辑:

所以像这样的东西?

[[f x | f <- [(+3),(*2)]] | x <- [1..2]]
[[4,2],[5,4]]
于 2012-08-25T17:42:22.073 回答
0

我无法从您的解释中找出任何东西,但这是一个可能的代码,它为您的示例提供了正确的答案:

> map (uncurry foldr1) [((+), [2,3]), ((*), [2,3])]
[5,6]
于 2012-08-25T17:53:44.197 回答
-1

我不知道它是否真的是你需要的,但是

Prelude> [f 2 3 | f <- [(+), (*)]]
[5,6]

如果您需要 <2,3> 对的列表,您可以使用类似

Prelude> [zipWith f [2, 20] [3, 30] | f <- [(+), (*)]]
[[5,50],[6,600]]
于 2012-08-25T17:39:10.763 回答