Haskell:如何停止程序打印左或右 [英] Haskell: How to stop program printing Left or Right

查看:103
本文介绍了Haskell:如何停止程序打印左或右的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经在GHCi内部运行过的haskell中制作了一个计算器。然而,由于最终的数字可以是一个整数或双精度,我已经做出了类型声明

  calc :: String  - >无论是整数Double 

然而,该函数的输出总是在其前面或左边或右边

 离开7 

对8.4

有没有办法阻止左右打印?

解决方案

幻想方式



(可能另一个不太好看的解决方案对你更好)



如果您只关注ghci,现在(GHC> = 7.6)使用自定义打印功能的可能性。您只需指定,例如,

 类型CalcResult =可以是整数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# - } 
{ - #语言UndecidableInstances# - }
{ - #LANGUAGE OverlappingInstances# - }

data CalcResult - 我们必须从$ b $中禁止'Either'的'Show'实例b = IntegerResult Integer - 阻止我们。 (无论如何,这种类型更好,
| FloatingResult Double - 你可能想添加更多类型(例如'Complex')
- 稍后,这对'Either'来说是不好的。)

类CalcShow c其中
calcShow :: c - >字符串

实例(显示c)=> CalcShow c其中
calcShow = show

实例CalcShow CalcResult其中
calcShow(IntegerResult intg)= show intg
calcShow(FloatingResult floatng)= show floatng

calcPrint :: CalcShow c => c - > IO()
calcPrint = putStrLn。 calcShow

通过这种方式,您可以按照自己喜欢的方式显示计算结果,任何旧的显示类:


ghci-7.6 GHCI_Customprint.hs - interactive-print = GHCI_Customprint.calcPrint

GHCi,版本7.6.2: http://www.haskell.org/ ghc / :?帮助

加载包ghc-prim ...链接... done。

加载包integer-gmp ...链接...完成。

加载包base ... linking ... done。

[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



另一个解决方案



正如我所说,您应该使用自定义数据类型作为结果,而不是或者。为什么,如果你有这样的类型,你可以给它一个 Show 实例,它可以做你想做的事:

  instance Show CalcResult其中
show(IntegerResult intg)= show intg
show(FloatingResult floatng)= show floatng

出于您的目的,这可能会很好,您可以在ghci中使用它,而无需进行任何额外的调整,并且它可以满足您的需求。只有, Show 实例应该生成有效的Haskell代码的一种规律。但是这其实很好,因为您可以为 CalcResult 3 27.8 有效的构造函数
pre code $ instance $ N $ CalcResult
fromInteger = IntegerResult
IntegerResult a + IntegerResult b = IntegerResult $ a + b
...

实例Floating CalcResult其中
fromRational = FloatingResult。 fromRational
...


I've made a calculator in haskell which I run from within GHCi. However since the final number can be an integer or double I've made the type declaration

calc :: String -> Either Integer Double

However the output of the function always has either left or right in front of it for example

Left 7

Right 8.4

Is there a way I can stop the left and right being printed?

解决方案

The fancy way

(Probably, the other, less fancy solution below is better for you)

If you're only concerned about ghci, there's now (GHC>=7.6) the possibility to use a custom print function. You'd just specify, say,

type CalcResult = Either Integer Double

calcPrint :: CalcResult -> IO()
calcPrint (Left intg) = print intg
calcPrint (Right floatng) = print floatng

and then load ghci by

$ ghci YourModule.hs -interactive-print=YourModule.calcPrint SpecPrinter

This way, it's going to be a bit annoying: calcPrint can only use CalcResult, so you wouldn't be able to display anything else. To get around this, you can use a type class,

{-# 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

This way you will be able to display calculation results the way you'd like, as well as anything in the old Show class:

$ 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

The other solution

As I said, you should be using a custom data type as your result, not Either. Why, if you have such a type you might as well give it a Show instance that does what you want:

instance Show CalcResult where
  show (IntegerResult intg) = show intg
  show (FloatingResult floatng) = show floatng

For your purposes, this will probably be just fine, you can use it in ghci without any extra tweaks and it does what you want. Only, there's a kind of law that a Show instance should produce valid Haskell code. But that's actually ok, because you can make 3 or 27.8 valid "constructors" for CalcResult!

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

instance Floating CalcResult where
  fromRational = FloatingResult . fromRational
  ...

这篇关于Haskell:如何停止程序打印左或右的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆