这是一个快速的概念性问题,我目前正在努力学习和更好地理解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对其内部的代码知之甚少.
除了使用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一两个实验的内部结构后,似乎可以重构为更广泛的覆盖更多功能.