为什么函数没有Show实例?

Jus*_*ler 7 haskell

这是一个快速的概念性问题,我目前正在努力学习和更好地理解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>
Run Code Online (Sandbox Code Playgroud)

ami*_*dfv 10

并不是他们不能,但通常没有充分的理由.

但如果你愿意,你绝对可以:

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.
Run Code Online (Sandbox Code Playgroud)

如果您想要show函数的文本表示,那么 - 你不能这样做.与Ruby,JS等元编程语言不同,Haskell对其内部的代码知之甚少.

  • 实际上内置了一个`Show`实例.这是常见问题 - [这里](http://stackoverflow.com/questions/15015698/derive-eq-and-show-for-type-alias-in-haskell/15015731#15015731)和[here](http://stackoverflow.com/questions/10551210/instance-show-for-function/10551513#10551513)例如. (3认同)

Dav*_*rak 8

除了使用Data.Typeable的所有函数的固定字符串之外,还有一个部分解决方案.

{-# LANGUAGE ScopedTypeVariables #-}

import Data.Typeable

instance (Typeable a, Typeable b) => Show (a->b) where
  show _ = show $ typeOf (undefined :: a -> b)
Run Code Online (Sandbox Code Playgroud)

在ghci

> let test :: Int->Int; test x = x + x
> test
Int -> Int
Run Code Online (Sandbox Code Playgroud)

不幸的是,没有类型签名,类型将默认为默认值.

> let test x = x + x
> test
Integer -> Integer
Run Code Online (Sandbox Code Playgroud)

此解决方案适用于多个功能区域,因为a -> b -> c它与a -> (b -> c)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
Run Code Online (Sandbox Code Playgroud)

但是,当不知道函数的参数是否具有可键入的类时,此方法不起作用,但是这样做虽然map (+1)不起作用map.

> map (+1)
[Integer] -> [Integer]
> map

<interactive>:233:1:
...
Run Code Online (Sandbox Code Playgroud)

在看了Data.Data一两个实验的内部结构后,似乎可以重构为更广泛的覆盖更多功能.