首先,我正在阅读的真实世界Haskell表示永远不会使用foldl而是使用foldl'.所以我相信它.
但我对什么时候使用foldrvs. 朦胧foldl'.虽然我可以看到他们如何以不同的方式摆放在我面前的结构,但是当"哪个更好"时,我太愚蠢了.我想在我看来似乎并不重要,因为它们都产生相同的答案(不是吗?).事实上,我以前使用这个结构的经验来自Ruby inject和Clojure reduce,它们似乎没有"左"和"右"版本.(附带问题:他们使用哪个版本?)
任何有助于像我这样的智能挑战的洞察力都会非常感激!
为什么编译器不能翻译Scala
(1,2,3,4,5,6).foldRight(10)(_ * _)
Run Code Online (Sandbox Code Playgroud)
与Java等效
final int[] intArray = new int[]{1,2,3,4,5,6};
int accumulator = 10;
for(int i = intArray.legth - 1; i >=0; i--) {
accumulator = intArray[i] * accumulator;
}
Run Code Online (Sandbox Code Playgroud)
问题是:为什么foldLeft和reduceLeft是尾递归的,但它们的右对手不是?
这里有链接说右手不是尾递归.我在问为什么会这样.
使用foldRight定义如下的concat函数可以正确连接列表
def concat[T](xs: List[T], ys: List[T]): List[T] = (xs foldRight(ys))(_ :: _)
Run Code Online (Sandbox Code Playgroud)
但是使用foldLeft这样做
def concat1[T](xs: List[T], ys: List[T]): List[T] = (xs foldLeft(ys))(_ :: _)
Run Code Online (Sandbox Code Playgroud)
导致编译错误value :: is not a member of type parameter T,需要帮助理解这种差异.
编辑:
以防万一有人可能正在寻找折叠的详细解释 http://lampwww.epfl.ch/teaching/programmation_avancee/documents/programmation_avancee_5_en-2x2.pdf
这已被讨论 到 死亡在这里如此,但我具体的例子是逃避我,因为我觉得我的折叠不应该关心无论是由右到左或左到右.这是2016年第1天代码出现的解决方案,归结为获取指令列表(向右/向左,向前走x步),应用它们,并给出你最终到达的地方与出租车几何之间的距离你开始了
我写了一个apply函数来处理这个旅程的一个步骤,它有签名:
data Direction = North | East | South | West deriving (Enum, Show)
type Location = (Int, Int)
type Instruction = String
apply :: Direction -> Location -> Instruction -> (Direction, Location)
Run Code Online (Sandbox Code Playgroud)
假设它正确实现(因为我测试了它,它是.我将在折叠下面包括一个可运行的例子).我注意到我可以使用折叠将其应用于整个指令列表,并且确实如此
(_, finalLocation) = foldr f (North, (0, 0)) instructions -- note the foldr.
where f = (\ins (d, loc) -> apply d loc ins)
Run Code Online (Sandbox Code Playgroud)
使用权利相关的折叠在这里工作,但给了我错误的答案.当我用foldl(和flip f)重新运行它时,我得到了一个完全不同的答案,其中接受了adventofcode,所以我承认折叠方向肯定是差异,我只是不知道为什么它有区别,因为在我看来我的代码不应该关心折叠发生的方式.
为什么我错了? …
我的印象是foldright从列表的末尾开始并向后工作(这就是我想象的右关联意味着什么).所以我很困惑,以下适用于无限列表.
我有一个功能find:
find :: (a -> Bool) -> List a -> Optional a
find p = foldRight (\c a -> if p c then Full c else a) Empty
Run Code Online (Sandbox Code Playgroud)
请注意以下工作:
>> find (const True) infinity
Full 0
Run Code Online (Sandbox Code Playgroud)
我做了一些搜索,发现这篇文章:你怎么知道何时使用fold-left以及何时使用fold-right?
不幸的是,接受的答案并不是特别有用,因为右关联操作的例子是:
A x (B x (C x D))
Run Code Online (Sandbox Code Playgroud)
这仍然意味着它需要首先执行最正确的事情.
我想知道是否有人能为我解决这个问题,谢谢.
fold在这里可以使用a 来将a转换List[JsObject]为JsArray吗?
def getJsonArray(list: List[JsObject]): JsArray = {
def go(l: List[JsObject], acc: JsArray) : JsArray = l match {
case x :: xs => go(xs, acc ++ Json.arr(x))
case Nil => acc
}
go(list, JsArray())
}
Run Code Online (Sandbox Code Playgroud)