我怎样才能让Show显示一个函数的名字? [英] How can I have Show display the name of a function?

查看:172
本文介绍了我怎样才能让Show显示一个函数的名字?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

作为一个简单的练习,让我了解Haskell,在Youtube上闲逛并陷入美国倒计时游戏节目后,我想为Numbers游戏做一个解算器。



您得到6个数字,需要将它们与(+)( - )(*)(/)结合以获得给定结果。





到目前为止,我脑中已经死了,

  let operands = [75 ,2,6,3,8,7] :: [Double] 
let goal = 623 :: Double
let operations = [(+),( - ),(*), ]
$ b $显示(头[(a,x,b,y,c,z,d,t,e)|
a < - 操作数,
b< - 过滤器(\ q-> q / = a)操作数,
c < - filter(\ q-> q / = a&& q / = b)操作数,
d< - 过滤器(\ q-> q / = a&& q / = b&& q / = c)操作数,
e < - filter(\ q - > q / =一个& ;& q / = b&& q / = c&&操作,
t操作,
t操作,$ b $操作,$ b $操作,
z操作,
t操作,
t(z y(xab)c)d)e == goal])

...但很明显Show doesn '不知道如何处理函数。

 没有用于(Show(Double  - > Double  - > Double)的实例) 
可能的修正:
添加一个实例声明(Show(Double - > Double - > Double))

我该如何解决这个问题?我是否需要混淆类型和数据构造函数来创建我自己的可以打印的函数或者是否有更简单的方法?

解决方案

我通常不会建议你为函数实现一个 Show 实例。这不是haskelly做事的方式,因此:

您定义了一种显示函数的规范方式。您可能希望现在将它们显示为它们的名称,但是如果您决定这样做:


add xy = add(x - 1)(y + 1)

operations = [...,add,...]

实际上,程序的输出应该根据您的内部实现而改变吗?这没有什么意义。另外,无名函数会发生什么情况?

另外,在程序的另一部分中,您可能希望将函数显示为它们的类型等,然后您'd有冲突显示实例。



通常,只执行 Show ,当你知道应该只有一种显示方式时,这种方式适用于所有需要显示的值。






解决这个问题最简单的方法可能就是将操作的名称和操作一起存储。像这样:

  let operations = [(+,(+)),( - ,( - )) ,(*,(*)),(/,(/))] 

- ...
show(head [(a,xname,b,yname ,c,zname,d,tname,e)|
a < - 操作数,
b < - 过滤器(\ q - > q / = a)操作数,
c <滤波器(\ q-> q / = a&& q / = b)操作数,
d< - 滤波器(\ q-> q / = a&& q / = b && q / = c)操作数,
e< - filter(\ q - > q / = a&& q / = b&& q / = c&操作数,
(xname,x)< - 操作,
(yname,y)< - 操作,
(zname,z)< b $ b(tname,t)< - 操作,
t(z(y(xab)c)d)e ==目标])


As a simple exercise to get me acquainted with Haskell, after idling around on Youtube and stumbling into the American Countdown game show, I wanted to make a solver for the Numbers game.

You get 6 numbers and need to combine them with (+) (-) (*) (/) in order to get a given result.

What I've got so far is the very brain-dead,

let operands = [75, 2, 6, 3, 8, 7] :: [Double]
let goal = 623 :: Double
let operations = [(+), (-), (*), (/)]

show (head [(a, x, b, y, c, z, d, t, e) |
      a <- operands,
      b <- filter (\ q -> q /= a) operands,
      c <- filter (\ q -> q /= a && q /= b) operands,
      d <- filter (\ q -> q /= a && q /= b && q /= c) operands,
      e <- filter (\ q -> q /= a && q /= b && q /= c && q /= d) operands,
      x <- operations,
      y <- operations,
      z <- operations,
      t <- operations,
      t (z (y (x a b) c) d) e == goal])

...but obviously Show doesn't know what to do with functions.

No instance for (Show (Double -> Double -> Double))
  arising from a use of `show'
Possible fix:
  add an instance declaration for (Show (Double -> Double -> Double))

How can I work around this? Do I need to mess with type and data constructors to make my own functions that can print or is there some easier way around it?

解决方案

I would generally not advise you to implement a Show instance for functions. It is not the "haskelly" way of doing things, for this reason:

You define a "canonical" way of showing functions. You might want them to be shown as their names now, but what if you decide to do this:

add 0 y = y
add x y = add (x - 1) (y + 1)

operations = [..., add, ...]

Should really the output of your program change depending on your internal implementation? That doesn't make much sense. Also, what happens to nameless functions?

Also, in another part of the program, you might want to show your functions as their types instead, etc., and then you'd have conflicting Show instances.

Generally, only implement Show when you know that there should be only one way of showing that thing, and that that way works for all values that need to be shown.


The simplest way of solving this problem would probably be to just store the name of the operation along with the operation. Like so:

let operations = [("+", (+)), ("-", (-)), ("*", (*)), ("/", (/))]

-- ...
show (head [(a, xname, b, yname, c, zname, d, tname, e) |
  a <- operands,
  b <- filter (\ q -> q /= a) operands,
  c <- filter (\ q -> q /= a && q /= b) operands,
  d <- filter (\ q -> q /= a && q /= b && q /= c) operands,
  e <- filter (\ q -> q /= a && q /= b && q /= c && q /= d) operands,
  (xname, x) <- operations,
  (yname, y) <- operations,
  (zname, z) <- operations,
  (tname, t) <- operations,
  t (z (y (x a b) c) d) e == goal])

这篇关于我怎样才能让Show显示一个函数的名字?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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