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