2015-09-14 31 views

回答

18

也許這是不是在所有(懶惰的快樂)評估 - 但如果它是,它應該只計算一次 - 如果你喜歡,你可以嘗試一下trace

import Debug.Trace(trace) 

func n = m ++ [1] ++ m ++ [0] ++ m 
    where m = func2 n 

func2 n = trace "called..." [n] 

這裏在GHCI一個例子:

λ> func 3 
called... 
[3,1,3,0,3] 

這裏是一個,你看,它可能不會被調用(直到你最後需要對其進行評估):

λ> let v = func 4 

λ> v 
called... 
[4,1,4,0,4] 

見:首先它不叫 - 只有當你最終評估v(打印出來),你得到的通話。只要你沒有禁用單態限制

8

卡斯滕的答案(該值將最多一次來計算)是正確的。如果你有,那麼m可能有一個多態類型推斷,涉及類型的類,然後m是不是一個真正的標準值,而是一個功能,需要一個類型的類字典併產生價值。考慮這個例子。

{-# LANGUAGE NoMonomorphismRestriction #-} 

import Debug.Trace(trace) 

func n = m ++ [1] ++ m ++ [0] ++ m 
    where m = func2 n      -- m :: Monad t => t a (where n :: a) 

func2 n = trace "called..." (return n) -- func2 :: Monad t => a -> t a 

然後評估在ghci中打印func 3

called... 
[3,1called... 
,3,0called... 
,3] 
+0

感謝 - 非常好的問題 - 我確實沒想到這裏的這個在所有。這真的很難給上Haskell的正確答案,當涉及到這樣的細節 - 通常有呈現你的直覺毫無價值的擴展:*( – Carsten

3

要添加到@ Carstan的和@Reid巴頓的回答,這也取決於你是否正在運行的編譯代碼或沒有,例如:

{-# LANGUAGE NoMonomorphismRestriction #-} 

import Debug.Trace(trace) 

func n = m ++ [1] ++ m ++ [0] ++ m 
    where m = func2 n      -- m :: Monad t => t a (where n :: a) 

func2 n = trace "called..." (return n) 

main = let xs = func 3 :: [Int] 
     in print xs 

ghci正在運行main打印出called 3次。但是,編譯時,使用-O2時僅打印出called一次。 (測試了7.10.2)

+0

你與優化編譯啓用我只有7.10.1,但我看到'叫什麼名字? '印刷3次編輯以及何時但可以肯定的優化還可以在一般的影響這種行爲 –

+0

是 - 。我和-02編譯我會澄清答案。 – ErikR