我在haskell中制作了一个计算器,我在GHCi中运行.但是由于最终的数字可以是整数或双数,所以我做了类型声明
calc :: String -> Either Integer Double
Run Code Online (Sandbox Code Playgroud)
但是,该功能的输出总是在其前面左侧或右侧
Left 7
Right 8.4
Run Code Online (Sandbox Code Playgroud)
有没有办法可以阻止左右打印?
(可能,下面另一个不那么花哨的解决方案对你来说更好)
如果您只关心ghci,现在(GHC> = 7.6)可以使用自定义打印功能.你只需要说明,
type CalcResult = Either Integer Double
calcPrint :: CalcResult -> IO()
calcPrint (Left intg) = print intg
calcPrint (Right floatng) = print floatng
Run Code Online (Sandbox Code Playgroud)
然后加载ghci
$ ghci YourModule.hs -interactive-print = YourModule.calcPrint SpecPrinter
这样一来,这将是一个有点恼人:calcPrint可以只使用CalcResult,所以你不能将能够显示任何东西.要解决这个问题,您可以使用类型类,
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE OverlappingInstances #-}
data CalcResult -- We must prevent the 'Show' instance of 'Either' from
= IntegerResult Integer -- getting in our way. (This type is better anyway,
| FloatingResult Double -- you might want to add more types (e.g. 'Complex')
-- later, which is no good with 'Either'.)
class CalcShow c where
calcShow :: c -> String
instance (Show c) => CalcShow c where
calcShow = show
instance CalcShow CalcResult where
calcShow (IntegerResult intg) = show intg
calcShow (FloatingResult floatng) = show floatng
calcPrint :: CalcShow c => c -> IO()
calcPrint = putStrLn . calcShow
Run Code Online (Sandbox Code Playgroud)
这样您就可以按照自己喜欢的方式显示计算结果,以及旧Show类中的任何内容:
$ ghci-7.6 GHCI_Customprint.hs -interactive-print = GHCI_Customprint.calcPrint
GHCi,版本7.6.2:http ://www.haskell.org/ghc/:?求助于
加载包ghc-prim ...链接...完成.
加载包integer-gmp ...链接...完成.
加载包基...链接...完成.
[1 of 1]编译GHCI_Customprint(GHCI_Customprint.hs,解释)
好的,模块加载:GHCI_Customprint.
*GHCI_Customprint>"blubb"
"blubb"
*GHCI_Customprint> [1..5]
[1,2,3,4,5]
*GHCI_Customprint> IntegerResult 39
39
*GHCI_Customprint> FloatingResult $ -236.24983e + 89
-2.3624983e91
正如我所说,你应该使用自定义数据类型作为结果,而不是Either.为什么,如果你有这样的类型,你可以给它一个Show实现你想要的实例:
instance Show CalcResult where
show (IntegerResult intg) = show intg
show (FloatingResult floatng) = show floatng
Run Code Online (Sandbox Code Playgroud)
为了您的目的,这可能会很好,您可以在ghci中使用它而无需任何额外的调整,它可以做你想要的.只有,Show实例应该生成有效的Haskell代码.但这实际上没问题,因为你可以制作3或27.8有效的"构造函数" CalcResult!
instance Num CalcResult where
fromInteger = IntegerResult
IntegerResult a + IntegerResult b = IntegerResult $ a+b
...
instance Floating CalcResult where
fromRational = FloatingResult . fromRational
...
Run Code Online (Sandbox Code Playgroud)
评估此功能时,GHCi会自动调用putStrLn . show结果.它的show功能Either Integer Double是添加Left和Right字符串.
为了避免这种情况,您可以使用either show show,它将仅将show函数应用于存储在其中的数字Either,因此
> putStrLn . either show show $ calc ...
Run Code Online (Sandbox Code Playgroud)
应该给你你想要的东西.