haw*_*eye 0 polymorphism haskell clojure
我选择使用Haskell的原因在于其丰富的类型系统.这在编译时为我提供了有关我的程序的更多信息,帮助我确信它是合理的.
此外,Haskell似乎是一种处理表达式问题的最佳语言,因为Haskell类型类可以在返回类型上进行调度.(与Clojure协议相反 - 它只能在第一个参数上调度).
当我探索Haskell多态返回值函数时read:
read :: (Read a) => String -> a
Run Code Online (Sandbox Code Playgroud)
使用以下程序:
addFive :: Int -> Int
addFive x = x + 5
main :: IO ()
main = do
print (addFive (read "11"))
putStrLn (read "11")
Run Code Online (Sandbox Code Playgroud)
我得到以下结果:
Runtime error
...
prog: Prelude.read: no parse
Run Code Online (Sandbox Code Playgroud)
所以我似乎在使用高级类型系统的语言中获得运行时错误.
将其与Clojure中的等效代码进行对比:
(defn add-five [x] (+ 5 x))
(println (add-five (read-string "11")))
(println (read-string "11"))
Run Code Online (Sandbox Code Playgroud)
这给出了以下结果:
16
11
Run Code Online (Sandbox Code Playgroud)
我的问题是为什么Haskell在返回类型多态中推断类型会导致运行时错误?不应该在编译时把它们拿起来吗?
该运行时错误与多态无关,而且与该"11"函数无法将字符串解析为字符列表这一事实有关read.
这是有用的东西.请注意"11",在运行时,可以将其解析为a,Int并且"\"Some More String\""可以在运行时将其解析为字符串.
print $ 5 + read "11"
print $ "Some string" ++ read "\"Some More String\""
Run Code Online (Sandbox Code Playgroud)
以下是一些不起作用的事情.他们不工作,因为"Not an integer"不能被解析为Int和"11"不能被解析为一个字符串.
print $ 5 + read "Not an integer"
print $ "Some string" ++ read "11"
Run Code Online (Sandbox Code Playgroud)
正如您在上一个问题的答案中指出的那样,类型信息已在编译时推断出来.该read功能已经被选定.试想一下,如果我们有两个功能readInt :: String -> Int,并readString :: String -> String得以提供的read功能为Read对实例Int和String分别.在编译时,编译器已经read用原始的相应函数替换了出现的情况:
print $ 5 + readInt "Not an integer"
print $ "Some string" ++ readString "11"
Run Code Online (Sandbox Code Playgroud)
这必须在编译时发生,因为在编译时消除了类型信息,正如您在上一个问题的答案中所解释的那样.