当用作多种类型的值时,如何处理这种多态值?

Mat*_*ick 3 polymorphism haskell

鉴于这行代码(我在这个答案中首次看到):

pVal :: Num a => a
pVal = sum . map fromIntegral $ ([1..10000000] :: [Int])
Run Code Online (Sandbox Code Playgroud)

如果它被用作多种类型,那么表达式是否为每种类型完全重新评估?每种类型都有一个结果吗?

例如:

pInt :: Int
pInt = pVal

pDub :: Double
pDub = pVal
Run Code Online (Sandbox Code Playgroud)

ham*_*mar 12

从技术上讲,Haskell标准没有规定.在实践中,每次都会重新评估.您可以使用Debug.Trace以下方法自行验证:

import Debug.Trace (trace)

pVal :: Num a => a
pVal = trace "evaluating..." $ sum . map fromIntegral $ ([1..10000] :: [Int])
Run Code Online (Sandbox Code Playgroud)

在GHCi中尝试:

> pVal :: Int
evaluating...
50005000
> pVal :: Int
evaluating...
50005000
Run Code Online (Sandbox Code Playgroud)

但是,将此值绑定到具体类型将允许重新使用它.

pInt :: Int
pInt = pVal
Run Code Online (Sandbox Code Playgroud)

注意第二次没有"评估......":

> pInt
evaluating...
50005000
> pInt
50005000
Run Code Online (Sandbox Code Playgroud)