繁体   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