【问题标题】:Haskell: How to stop program printing Left or RightHaskell:如何停止向左或向右打印程序
【发布时间】:2013-04-29 04:50:21
【问题描述】:

我在 Haskell 中制作了一个计算器,我在 GHCi 中运行它。但是,由于最终数字可以是整数或双精度数,因此我已经进行了类型声明

calc :: String -> Either Integer Double

但是,例如,函数的输出总是在其前面有左边或右边

Left 7

Right 8.4

有什么方法可以阻止左右打印吗?

【问题讨论】:

    标签: haskell types


    【解决方案1】:

    当你评估这个函数时,GHCi 会自动调用putStrLn . show 的结果。这是Either Integer Doubleshow 函数,它添加了LeftRight 字符串。

    为避免这种情况,您可以改用either show show,它只会将show 函数应用于存储在Either 中的数字,所以

    > putStrLn . either show show $ calc ...
    

    应该给你你想要的。

    【讨论】:

    • 更好的是,定义自己的打印函数:p = putStrLn . either show show
    【解决方案2】:

    别致的方式

    (可能下面的另一种不太花哨的解决方案更适合您)

    如果您只关心 ghci,现在有 (GHC>=7.6)the possibility to use a custom print function。你只需指定,比如说,

    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,版本 7.6.2:http://www.haskell.org/ghc/:?寻求帮助
    加载包 ghc-prim ... 链接 ... 完成。
    正在加载包 integer-gmp ... 链接 ... 完成。
    正在加载包库...链接...完成。
    [1 of 1] 编译 GHCI_Customprint(GHCI_Customprint.hs,解释)
    好的,已加载模块:GHCI_Customprint。
    *GHCI_Customprint> “布卢布”
    “布卢布”
    *GHCI_Customprint> [1..5]
    [1,2,3,4,5]
    *GHCI_Customprint> 整数结果 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 生成 327.8 有效的“构造函数”!

    instance Num CalcResult where
      fromInteger = IntegerResult
      IntegerResult a + IntegerResult b = IntegerResult $ a+b
      ...
    
    instance Floating CalcResult where
      fromRational = FloatingResult . fromRational
      ...
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-04-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-29
      • 2013-02-14
      • 1970-01-01
      相关资源
      最近更新 更多