我在Haskell中制作了一个计算器,我从GHCi中运行它。然而,由于最终数字可以是整数或双精度浮点数,因此我进行了类型声明。
calc :: String -> Either Integer Double
然而,该函数的输出始终在其前面添加左侧或右侧,例如:
Left 7
Right 8.4
有没有办法停止打印左右两侧的内容?
(也许,下面的另一种不那么高级的解决方案更适合您)
如果您只关心ghci,现在(GHC>=7.6)有使用自定义打印函数的可能性。您只需指定:
type CalcResult = Either Integer Double
calcPrint :: CalcResult -> IO()
calcPrint (Left intg) = print intg
calcPrint (Right floatng) = print floatng
然后通过以下方式加载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
Show
类中的任何内容了:
$ ghci-7.6 GHCI_Customprint.hs -interactive-print=GHCI_Customprint.calcPrint
GHCi, version 7.6.2: http://www.haskell.org/ghc/ :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
[1 of 1] Compiling GHCI_Customprint ( GHCI_Customprint.hs, interpreted )
Ok, modules loaded: 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
对于您的目的,这可能就足够了,您可以在ghci中使用它而不需要任何额外的调整,并且它可以完成您想要的工作。只是,有一种法律规定Show
实例应该生成有效的Haskell代码。但这实际上是可以的,因为您可以为CalcResult
创建3
或27.8
有效的“构造函数”!
instance Num CalcResult where
fromInteger = IntegerResult
IntegerResult a + IntegerResult b = IntegerResult $ a+b
...
instance Floating CalcResult where
fromRational = FloatingResult . fromRational
...
putStrLn . show
。它是用于Either Integer Double
的show
函数,该函数将添加Left
和Right
字符串。either show show
,它仅将show
函数应用于Either
中存储的数字,因此> putStrLn . either show show $ calc ...
应该能给您想要的东西。
p = putStrLn . either show show
。 - Gabriella Gonzalez