我有这个相当简单的函数来计算大列表元素的平均值,使用两个累加器来保存到目前为止的总和以及到目前为止的计数:
mean = go 0 0
where
go s l [] = s / fromIntegral l
go s l (x:xs) = go (s+x) (l+1) xs
main = do
putStrLn (show (mean [0..10000000]))
Run Code Online (Sandbox Code Playgroud)
现在,用严格的语言,这将是尾递归,并且没有问题.然而,由于Haskell很懒,我的谷歌搜索让我明白(s + x)和(l + 1)将作为thunk传递递归.所以整件事崩溃和烧伤:
Stack space overflow: current size 8388608 bytes.
Run Code Online (Sandbox Code Playgroud)
进一步的谷歌搜索后,我发现seq和$!.这似乎我不理解,因为我在这种情况下使用它们的所有尝试都证明是徒劳的,错误信息说的是关于无限类型的东西.
最后我发现-XBangPatterns,它通过改变递归调用来解决所有问题:
go !s !l (x:xs) = go (s+x) (l+1) xs
Run Code Online (Sandbox Code Playgroud)
但我对此并不满意,因为-XBangPatterns目前这是一个扩展.我想知道如何在不使用的情况下严格评估-XBangPatterns.(也许还可以学到一些东西!)
只是让你理解我缺乏理解,这就是我尝试过的(编译的唯一尝试,即):
go s l (x:xs) = go (seq s (s+x)) (seq l (l+1)) xs …Run Code Online (Sandbox Code Playgroud) 我有一个Ruby的情况,可能需要创建一个对象,但它不确定.由于对象的创建可能代价高昂,因此我并不急于创建它.我认为这是延迟加载的明显案例.如何定义仅在有人向其发送消息时才创建的对象?该对象将在块中创建.有没有办法在Ruby中进行简单的延迟加载/初始化?这些东西是否支持这些东西,它们为各种懒惰的对象初始化提供了不同的解决方案?谢谢你的建议!
可以LAZY使用HQL 覆盖LEFT JOIN FETCH.
FROM Obj AS obj LEFT JOIN FETCH obj.otherObj WHERE obj.id = :id
Run Code Online (Sandbox Code Playgroud)
是否也可以覆盖EAGER?怎么样?
很抱歉,这听起来像是一个非常愚蠢的问题.
但我用Google搜索了网络,并专门搜索了php.net网站和stackoverflow.com网站.
我知道PHP在使用and, or, &&, ||运算符时会进行短路延迟评估,但在PHP手册中它的声明清晰明了?
我发现只有维基百科是唯一的'可信'来源,它说PHP对这些运营商进行了懒惰的评估.
更新:好的,这个问题可能非常简单.
q <- mapM return [1..]
Run Code Online (Sandbox Code Playgroud)
为什么这永远不会回来?
mapM是不是懒得处理无限列表?
下面的代码挂起.但是,如果我用线B替换A线,它就不会再挂起了.或者,如果我在A行之前加上"splitRandom $",它也不会挂起.
Q1是:mapM不是懒惰的吗?否则,为什么用线B替换A行"修复此"代码?
Q2是:为什么前面的A行与splitRandom"解决"了这个问题?
import Control.Monad.Random
import Control.Applicative
f :: (RandomGen g) => Rand g (Double, [Double])
f = do
b <- splitRandom $ sequence $ repeat $ getRandom
c <- mapM return b -- A
-- let c = map id b -- B
a <- getRandom
return (a, c)
splitRandom :: (RandomGen g) => Rand g a -> Rand g a
splitRandom code = evalRand code <$> getSplit
t0 …Run Code Online (Sandbox Code Playgroud) 我想知道:编写与用户或其他程序通过stdin和stdout交互的Clojure程序的最佳方法是什么?
显然,有可能编写某种命令式循环,但我希望找到一些更懒惰/功能的东西,有点受Haskell的"交互"功能的启发.
command-line functional-programming interactive clojure lazy-evaluation
我已多次读过Haskell中的懒惰评估有时会导致空间泄漏.什么样的代码会导致空间泄漏?如何检测它们?并且程序员可以采取哪些预防措施来避免它们?
不像其他不安全*操作,文档的unsafeInterleaveIO是不是其可能存在的缺陷非常明显的.那么到底什么时候不安全?我想知道并行/并发和单线程使用的条件.
更具体地说,以下代码中的两个函数在语义上是等价的吗?如果没有,何时以及如何?
joinIO :: IO a -> (a -> IO b) -> IO b
joinIO a f = do !x <- a
!x' <- f x
return x'
joinIO':: IO a -> (a -> IO b) -> IO b
joinIO' a f = do !x <- unsafeInterleaveIO a
!x' <- unsafeInterleaveIO $ f x
return x'
Run Code Online (Sandbox Code Playgroud)
以下是我在实践中如何使用它:
data LIO a = LIO {runLIO :: IO a}
instance Functor LIO where
fmap f (LIO a) = LIO …Run Code Online (Sandbox Code Playgroud) 据我所知!(称为bangs)用于表示应严格评估表达式.但对于我来说,将它们放在哪里或者根本不是那么明显.
import qualified Data.Vector.Unboxed as V
main :: IO ()
main = print $ mean (V.enumFromTo 1 (10^9))
mean :: V.Vector Double -> Double
Run Code Online (Sandbox Code Playgroud)
不同版本的意思是:
-- compiled with O2 ~ 1.14s
mean xs = acc / fromIntegral len
where !(len, acc) = V.foldl' f (0,0) xs :: (Int, Double)
f (len, acc) x = (len+1, acc+x)
-- compiled with O2 ~ 1.18s
mean xs = acc / fromIntegral len
where (!len, !acc) = V.foldl' f (0,0) xs :: …Run Code Online (Sandbox Code Playgroud) 只是好奇:在Kotlin中,我很想得到一些可以通过懒惰来初始化的val,但是有一个参数.那是因为我需要为了初始化它而创建的东西很晚.
具体来说,我希望我有:
private lateinit val controlObj:SomeView
Run Code Online (Sandbox Code Playgroud)
要么:
private val controlObj:SomeView by lazy { view:View->view.findViewById(...)}
Run Code Online (Sandbox Code Playgroud)
然后:
override fun onCreateView(....) {
val view = inflate(....)
controlObj = view.findViewById(...)
Run Code Online (Sandbox Code Playgroud)
或在第二种情况下controlObj.initWith(view)或类似的情况:
return view
Run Code Online (Sandbox Code Playgroud)
我无法使用,by lazy因为by lazy初始化时不会接受外部参数.在这个例子中 - 包含view.
当然我有,lateinit var但如果我能确保它在设置后变为只读,我会在一行中完成它会很好.
是否有一种非常干净的方法来创建只读初始化一次的只读变量,但只有当其他变量出生时?任何init once关键字?在init之后,编译器知道它是不可变的?
我知道这里存在潜在的并发问题,但如果我敢于在init之前访问它,我当然应该被抛出.
lazy-evaluation ×10
haskell ×5
ghc ×2
optimization ×2
performance ×2
android ×1
clojure ×1
command-line ×1
eager ×1
fetch ×1
hibernate ×1
hql ×1
immutability ×1
interactive ×1
kotlin ×1
lazy-loading ×1
monads ×1
php ×1
ruby ×1
space-leak ×1