簡體   English   中英

為什么沒有Show函數實例?

[英]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 -> ca -> (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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM