我编写这个示例是为了更好地理解 OCaml 中惰性求值的工作原理 - 使用 thonks。
let rec imp n = fun () -> imp(n*n);;
Run Code Online (Sandbox Code Playgroud)
我对惰性求值/thonks 的理解是, impl 会按照我调用的频率对初始数字进行平方
imp ()。
然而这个函数imp会引发以下错误:
---
let rec imp n acc = fun()->(***imp (n\*acc)***);;
This expression has type int -> unit -> 'a
but an expression was expected of type 'a
The type variable 'a occurs inside int -> unit -> 'a
---
Run Code Online (Sandbox Code Playgroud) 考虑这个 Haskell 程序
module RecursiveArray where
import Data.Array ( (!), listArray, Array )
goodArray :: Array Int Int
goodArray = listArray (0, 1) (go 0)
where
go x = x : go ((goodArray ! x) + 1)
badArray :: Array Int Int
badArray = listArray (0, 1) (go 0)
where
go !x = x : go ((badArray ! x) + 1)
main = do
print goodArray
print badArray
Run Code Online (Sandbox Code Playgroud)
哪个将打印
> runghc "RecursiveArray.hs"
array (0,1) [(0,0),(1,0)]
array <program stalls here>
Run Code Online (Sandbox Code Playgroud)
我需要一些帮助来理解这里发生的事情。人们可以使用等式推理来理解正在发生的事情吗?数组内部表示相关吗? …
我想将图像像素延迟加载到3维整数数组.例如,它看起来像这样:
for i=0 to Width
for j=0 to Height
let point=image.GetPixel(i,j)
pixels.[0,i,j] <- point.R
pixels.[1,i,j] <- point.G
pixels.[2,i,j] <- point.B
Run Code Online (Sandbox Code Playgroud)
如何以懒惰的方式制作?
如果我尝试> fst(a, b)在哪里a,b未定义,我得到未定义的错误b.即使尝试snd(a, b)它也会b导致错误.我有命令式编程的背景知识.我想知道这是否是某种我不理解的懒惰.
我正在尝试执行Django查询:
#att.name is a string
kwargs = {att.name : F('node__product__' + att.name) }
temps = Temp.objects.exclude(**kwargs)
Run Code Online (Sandbox Code Playgroud)
我想知道这是否正确.到目前为止我看到的所有示例都在值中使用字符串,但是如果值是函数,我应该将值设为字符串,就像这样吗?
kwargs = {att.name : 'F('node__product__' + att.name)' }
Run Code Online (Sandbox Code Playgroud)
值中的函数是否在参数列表中急切执行,还是等到需要它?
什么时候在Scala lazy val初始化?换句话说,以下代码将变量声明为惰性有一些好处吗?
lazy val xOption = table.get(x)
lazy val yOption = table.get(y)
lazy val xyOption = table.get(x + y)
(xOption, yOption, xyOption) match { ... }
Run Code Online (Sandbox Code Playgroud)
matchoperator(方法)是否初始化所有三个变量?
我在斯卡拉一个新手,并与懒惰的评价玩弄和这个问题跌跌撞撞:如果我想使懒惰的评估VALÇ作品,我写的虚拟变量一和b的声明之前Ç,这我考虑太多样板.我尝试在没有初始初始化的情况下声明a和b lazy val,但编译器抱怨.如果我写的东西:lazy val c = a:Double, b:Int也不起作用.
有没有办法摆脱这些虚拟变量?我能以更优雅的方式重构此代码吗?
var a = 0d; //> a : Double = 0.0
var b = 0; //> b : Int = 0
lazy val c = a / b //> c : Double = <lazy>
//some other code...
a = math.Pi
b = -1
(1 to 10).foreach(x => println(f"$x, ${x * c}%.8s"))
//> 1, -3.14159
//| 2, -6.28318
Run Code Online (Sandbox Code Playgroud) 所以我是Haskell的新手,我想弄清楚为什么我的天真实现实际上比我认为更智能的解决方案更快.
我正在尝试编写一个函数,给定一个String将返回一个Bool指示String是否使用一个且恰好是一个元音的函数.以下是我天真的实现:
singleVowel :: Maybe String -> Bool
singleVowel Nothing = False
singleVowel (Just s) = singleVowel (Just s) = length (nub $ filter (`elem` "aeiouyAEIOUY") s) == 1
Run Code Online (Sandbox Code Playgroud)
请注意,我过滤掉了元音集中没有的所有元素.然后,我使用该nub函数进行另一次传递,从筛选列表中删除重复项,并查看列表中是否只有1个元音.然后在最坏的情况下,此解决方案将使用O(n)内存和时间,因为它必须为筛选列表分配内存.
现在对于我的另一个解决方案,我决定使用递归并在每次递归调用时传递一个字符,以便在看到当前元音时跟踪当前元音.
singleVowelFaster :: Maybe String -> Bool
singleVowelFaster Nothing = False
singleVowelFaster (Just s) = singleVowelHelper s Nothing
singleVowelHelper :: String -> Maybe Char -> Bool
singleVowelHelper [] Nothing = False
singleVowelHelper [] _ = True
singleVowelHelper (x:xs) Nothing = if x …Run Code Online (Sandbox Code Playgroud) 我正在阅读Phobos文档并找到完成"懒惰迭代给定目录"的方法dirEntries.但我无法理解它的真正利润.
据我所知,懒惰函数意味着仅在需要时计算的函数.
我们来看下一个代码:
auto files = dirEntries(...);
auto cnt = files.count;
foreach( file; files ) { }
Run Code Online (Sandbox Code Playgroud)
dirEntries会叫多少次?一个或两个?请解释我的逻辑.
或者例如分离器
对我而言,使代码更难以理解.
它表明ghci下面是懒惰的,
ghci > let x = trace "1" 1 in x + x
1
1
2
Run Code Online (Sandbox Code Playgroud)
编译后运行下面的代码显示默认值ghc由严格性分析器增强.
main = do print $ let x = trace "1" 1 in x + x
1
2
Run Code Online (Sandbox Code Playgroud)
但是,即使将选项-O0 -fno-strictness传递给结果,为什么结果仍然相同ghc?
lazy-evaluation ×10
haskell ×4
scala ×2
arrays ×1
d ×1
django ×1
dummy-data ×1
f# ×1
hugs ×1
kwargs ×1
ocaml ×1
performance ×1
pixel ×1
python ×1
refactoring ×1
strictness ×1