[英]Why is there no Show instance for functions?
只是一個快速的概念性問題,我目前正在嘗試更好地學習和理解Haskell。
我知道Show函數用於將值轉換為字符串,但是為什么不能在show中使用函數類型?
Prelude> (\x -> x*3)
<interactive>:7:1:
No instance for (Show (a0 -> a0))
arising from a use of `print'
Possible fix: add an instance declaration for (Show (a0 -> a0))
In a stmt of an interactive GHCi command: print it
Prelude>
不是因為他們做不到,而是通常沒有充分的理由。
但是,如果您願意,您絕對可以:
Prelude> :{
Prelude| instance Show (a -> b) where
Prelude| show _ = "A function."
Prelude| :}
Prelude> print (\x -> x + 7)
A function.
Prelude> print (\a b c -> a + b + c)
A function.
如果您想show
該函數的文本表示形式,那么-您不能這樣做。 與元編程語言(如Ruby,JS等)不同,Haskell對自身內部結構的了解很少。
對於使用Data.Typeable的所有函數,有一部分解決方案不只是固定字符串。
{-# LANGUAGE ScopedTypeVariables #-}
import Data.Typeable
instance (Typeable a, Typeable b) => Show (a->b) where
show _ = show $ typeOf (undefined :: a -> b)
在ghci
> let test :: Int->Int; test x = x + x
> test
Int -> Int
不幸的是,如果沒有類型簽名,該類型將默認使用它。
> let test x = x + x
> test
Integer -> Integer
此解決方案適用於多種功能變量,因為a- a -> b -> c
與a -> (b -> c)
,您也可以將其寫為a- a -> d
,其中d = b -> c
。
> let m10 a b c d e f g h i j = a * b * c * d * e * f * g * h* i * j
> m10
Integer -> Integer -> Integer -> Integer -> Integer -> Integer -> Integer
-> Integer -> Integer -> Integer -> Integer
但是,如果未知函數的參數是否具有可鍵入的類,則此方法將不起作用,因此map (+1)
起作用時map
不會起作用。
> map (+1)
[Integer] -> [Integer]
> map
<interactive>:233:1:
...
看完Data.Data
的內部Data.Data
和一個或兩個實驗之后,似乎可以將其重構為更具通用性的功能。
show
是在Show
類型類的成員的函數上定義的函數(如果您不知道類型類是什么,則有點像OOP接口)。
默認情況下,函數不是typeclass的成員,因此我們無法打印它們。
我們可以使它成為typeclass的成員
instance Show (a -> b) where
show f = "Unicorns!!"
但是在這里我們知道為什么默認情況下不實現它。 沒有簡單,明顯的函數表示,並且haskell不想猜測,因此沒有實例。
唯一的“允許”實例將是實際打印出該函數的實例,但這將需要實際的語言更改,即將其硬連線到編譯器中,這在少數情況下不值得使用,這是不值得的。
更重要的是,這是不平凡的編譯器更改,Haskell已編譯,這意味着f = g
與
f = g
完全迷失了它。 但是,您絕對希望在函數表示中使用它。 因此,您必須在整個程序中使用該字符串。 絕對不是您想要的二進制文件。
如果您真的想要它打印獨角獸! 不過,請放心。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.