Haskell中有show
函数列表的方法吗?当我尝试
ghci> let functions = [(+), (-), (*)]
ghci> functions
GHCi说:
<interactive>:17:1:
No instance for (Show (Num a0 => a0 -> a0 -> a0))
arising from a use of 'print'
Possible fix:
add an instance declaration for (Show (Num a0 => a0 -> a0 -> a0))
In a stmt of an interactive GHCi command: print it
我不确定如何为此添加实例声明。任何帮助将不胜感激。感谢。
答案 0 :(得分:8)
您无法轻松显示功能。标准答案是
instance Show (a -> b) where
show _ = "<function>"
Prelude> [(+), (-), (*)]
[<function>,<function>,<function>]
这使您可以拥有一个show实例,但不提供有用的信息。这通常是正确的,因为可能没有紧凑的方式来显示函数的效果。此外,值得注意的是,虽然标准做法是考虑函数un - show
- 能够,如果你确实定义了这个实例,你可能会得到一个重叠的实例条件,就像instance (...) => Show (a -> b)
之类的任何实例一样。孤儿和非常一般。经验法则应该是应用程序代码中的确定,但在库中是危险的。
但是,除此之外,我们可以为instance Show (a -> b)
制作更好的功能。
如果您知道您的函数有一个有界输入,那么您可以做得更好
-- | A type instantiates 'Universe' if 'universe' is a
-- list of every value instantiating the type
class Universe a where
universe :: [a]
instance Universe Bool where
universe = [True, False]
instance (Universe a, Show a, Show b) => Show (a -> b) where
show f = show $ map (\a -> (a, f a)) universe
Prelude> (&&)
[ (True, [ (True,True)
, (False,False)
])
, (False, [ (True,False)
, (False,False)
])
]
最后,我们可以使用Data.Typeable
机制为函数获取更好的摘要show
,如果这是可以接受的。
import Data.Typeable
instance (Typeable a, Typeable b) => Show (a -> b) where
show f = "{ Function :: " ++ (show $ typeOf f) ++ " }"
Prelude Data.Typeable> [(+), (-), (*)]
[ { Function :: Integer -> Integer -> Integer }
, { Function :: Integer -> Integer -> Integer }
, { Function :: Integer -> Integer -> Integer }
]
但请注意,这会在多态函数上失败。
Prelude Data.Typeable> ($)
<interactive>:7:1:
No instance for (Typeable b0) arising from a use of `print'
The type variable `b0' is ambiguous
Possible fix: add a type signature that fixes these type variable(s)
Note: there are several potential instances:
instance [overlap ok] Typeable ()
-- Defined in `Data.Typeable.Internal'
instance [overlap ok] Typeable Bool
-- Defined in `Data.Typeable.Internal'
instance [overlap ok] Typeable Char
-- Defined in `Data.Typeable.Internal'
...plus 18 others
In a stmt of an interactive GHCi command: print it
Prelude Data.Typeable> ($) :: (() -> ()) -> () -> ()
{ Function :: (() -> ()) -> () -> () }