我正在使用项目Euler来自学Haskell,而且我在编写有关我的代码是如何被haskell执行时遇到了一些麻烦.第二个问题让我计算所有偶数斐波那契数的总和高达400万.我的脚本看起来像这样:
fibs :: [Integer]
fibs = 1 : 2 : [ a+b | (a,b) <- zip fibs (tail fibs)]
evens :: Integer -> Integer -> Integer
evens x sum | (even x) = x + sum
| otherwise = sum
main = do
print (foldr evens 0 (take 4000000 fibs))
Run Code Online (Sandbox Code Playgroud)
Hugs给出错误"垃圾收集无法回收足够的空间",我认为这意味着列表条目不会因为它们被消耗而被释放foldr.
我需要做些什么来解决这个问题?我尝试编写一个使用累加器的尾递归(我认为)版本,但也无法使用它.
我正在尝试使用hFlush来读取整个文件的程序,以避免我遇到的与懒惰IO有关的问题.
readHandle <- openFile fileName ReadMode
hSetBuffering readHandle $ BlockBuffering (Just 2048)
fileText <- hGetContents readHandle
hFlush readHandle
hClose readHandle
Run Code Online (Sandbox Code Playgroud)
这只是给我错误:hFlush:非法操作(句柄关闭)
有人可以帮我理解发生了什么
我最近安装了Ruby 2.0.0,发现它现在有一个懒惰的方法用于Enumerable mixin.根据之前的函数式语言经验,我知道这可以提高代码的效率.
我做了一个懒惰与渴望的基准(不确定是否是没有实际意义),并发现懒惰持续更快.为什么是这样?什么使得懒惰评估更适合大输入?
基准代码:
#!/usr/bin/env ruby
require 'benchmark'
num = 1000
arr = (1..50000).to_a
Benchmark.bm do |rep|
rep.report('lazy') { num.times do ; arr.lazy.map { |x| x * 2 }; end }
rep.report('eager') { num.times do ; arr.map { |x| x * 2}; end }
end
Run Code Online (Sandbox Code Playgroud)
基准报告样本:
user system total real
lazy 0.000000 0.000000 0.000000 ( 0.009502)
eager 5.550000 0.480000 6.030000 ( 6.231269)
Run Code Online (Sandbox Code Playgroud) 之前我在Scala中使用延迟评估时提出了一个问题.我试图在Scala中编写以下Haskell函数:
fib a b = c : (fib b c)
where c = a+b
Run Code Online (Sandbox Code Playgroud)
这个问题的答案是我不能使用Lists,而应该使用Streams.现在我想在Javascript中做同样的事情.我翻译了这个功能,并在这个网站上试了一下:
function fib(a,b) {
c = a+b;
return [c] + fib(b,c);
}
var res = fib(0,1).slice(0,10);
console.log(res);
Run Code Online (Sandbox Code Playgroud)
但是我收到以下错误:
RangeError: Maximum call stack size exceeded
Run Code Online (Sandbox Code Playgroud)
Javascript有办法做到这一点吗?
原谅我的愚蠢问题,我是Haskell的新手.
我在Haskell中尝试了以下内容:
sum [fib n| n <- [1..], (even (fib n) && fib n < 4000000)]
Run Code Online (Sandbox Code Playgroud)
这需要无限的时间.如果我遗漏n <- [1..],解决方案立即出现.
我认为这无关紧要,因为Haskell正在评估懒惰.我是否误解了懒惰的评价?
在Swift中,我们可以设置一个存储属性来使用闭包:
class Test {
var prop: String = {
return "test"
}()
}
Run Code Online (Sandbox Code Playgroud)
VS
或者使懒惰的存储属性使用闭包:
class Test {
lazy var prop: String = {
return "test"
}()
}
Run Code Online (Sandbox Code Playgroud)
在这两种情况下,用于获取属性值的代码仅运行一次.看起来它们是等价的.
在使用闭包时,我应该何时使用延迟存储属性与计算属性?
假设我有一个叫做数字的懒惰序列给我一个无限的数字序列:0,1,2,3,4,5,6 ......
(def numbers (iterate inc 0))
Run Code Online (Sandbox Code Playgroud)
我通过将其传递给函数take来限制无穷大.例如:
(take 3 numbers)
; > (0 1 2)
Run Code Online (Sandbox Code Playgroud)
我问自己如何为懒惰序列的成员添加一些后处理.更具体地说:当我使用take时,如何声明一个产生以下输出的函数"numbers-doubled":
(take 3 numbers-doubled)
; > ("00" "11" "22")
Run Code Online (Sandbox Code Playgroud) functional-programming clojure lazy-evaluation lazy-sequences clojurescript
这个问题是关于优化惰性集合的。我将首先解释问题,然后对可能的解决方案进行一些思考。问题以粗体显示。
Swift期望对Collections的操作为O(1)。一些操作中,特别是prefix与suffix样类型,偏离且为O(n)或更高的量级上。
延迟集合不能在初始化期间遍历基本集合,因为应该将计算尽可能长地延迟,直到实际需要该值为止。
那么,我们如何优化惰性集合?当然,这引出了一个问题,什么构成了优化的惰性集合?
最明显的解决方案是缓存。这意味着第一次调用集合的方法具有不利的时间复杂度,但是随后可以在O(1)中计算对相同或其他方法的后续调用。为了更快的计算,我们将一些空间复杂度交易为O(n)的数量级。
尝试struct通过缓存优化s 上的惰性集合是不可能的,因为subscript(_ position:)您需要实现的所有其他方法都必须LazyProtocolCollection是non-,mutating并且structs默认是不可变的。这意味着我们必须为每次调用属性或方法重新计算所有操作。
这给我们留下了classes。类是可变的,这意味着所有计算的属性和方法都可以在内部改变状态。当我们使用类优化延迟集合时,我们有两个选择。首先,如果惰性类型的属性是variable,那么我们将自己带入一个充满痛苦的世界。如果更改属性,则可能会使先前缓存的结果无效。我可以想象管理代码路径以使属性可变为令人头疼的问题。其次,如果我们使用lets ,那么我们很好。初始化期间设置的状态无法更改,因此不需要更新缓存的结果。请注意,此处我们仅讨论的是带有纯方法且没有副作用的惰性集合。
但是类是引用类型。将引用类型用于惰性集合有什么弊端?Swift标准库不使用它们作为入门。
对不同的方法有什么想法或想法吗?
这个问题是关于PL如何工作的好奇心,而不是其他任何问题.(实际上,我看到的是SML,它与Haskell的不同之处在于前者使用call-by-value - 但我的问题是关于Haskell.)
Haskell(据我所知)有"按需调用"语义.这是否意味着如果我定义一个函数如下:
cond True thenExp elseExp = thenExp
cond _ thenExp elseExp = elseExp
Run Code Online (Sandbox Code Playgroud)
这将总是表现得像if-then-else表达式?或者,在另一种意义上,if-then-else可以被视为可以被定义为函数的东西的语法糖?
编辑:
只是为了对比Haskell与Standard ML的行为,定义(在SML中)
cond p t f = if p then t else f;
然后是阶乘函数
fun factc n = cond (n=0) 1 (n * factc (n-1));
评估factc 1(说)永远不会完成,因为最后一个参数中的递归cond永远不会终止.
但是,定义
fun fact n = if n=0 then 1 else fact (n-1);
按预期工作,因为then分支仅根据需要进行评估.
也许有一些聪明的方法可以推迟SML中的参数评估(不知道我还不熟悉它)但重点是,在一个按值调用的类型语言中,if-then-else通常表现不同.我的问题是这是否(按需调用与按价值调用)是这种差异背后的主要原因(并且共识似乎是"是").
我正在尝试实现自己的应用解析器,这是我使用的代码:
{-# LANGUAGE ApplicativeDo, LambdaCase #-}
module Parser where
-- Implementation of an Applicative Parser
import Data.Char
import Control.Applicative (some, many, empty, (<*>), (<$>), (<|>), Alternative)
data Parser a = Parser { runParser :: String -> [(a, String)] }
instance Functor Parser where
-- fmap :: (a -> b) -> (Parser a -> Parser b)
fmap f (Parser p) = Parser (\s -> [(f a, s') | (a,s') <- p s])
instance Applicative Parser where
-- pure :: a -> …Run Code Online (Sandbox Code Playgroud) lazy-evaluation ×10
haskell ×6
swift ×2
applicative ×1
clojure ×1
closures ×1
fibonacci ×1
io ×1
javascript ×1
optimization ×1
parsing ×1
ruby ×1
space ×1