Church Numerals in haskell

一笑奈何 提交于 2019-12-06 23:27:57

问题


I am trying to print church numerals in haskell using the definions:

0 := λfx.x
1 := λfx.f x

Haskell code:

c0 = \f x -> x
c1 = \f x -> f x

When I enter it in the haskell console I get an error which says

    test> c1

    <interactive>:1:0:
    No instance for (Show ((t -> t1) -> t -> t1))
      arising from a use of `print' at <interactive>:1:0-1
    Possible fix:
      add an instance declaration for (Show ((t -> t1) -> t -> t1))
    In a stmt of an interactive GHCi command: print it

I am not able to exactly figure out what error says.

Thank you!


回答1:


The problem here is that, by default, it's not possible to print values in Haskell. The default way to print things--used by the print function and by the GHCi REPL, among others--is the show function, defined by the type class Show.

The error you're getting, then, is informing you that you've evaluated an expression of a type that doesn't have an instance of Show defined. Modulo some verbiage, this is all the error message is saying:

No instance for (Show ((t -> t1) -> t -> t1))

The type ((t -> t1) -> t -> t1) is what was inferred for the expression you evaluated. This is a valid type for the Church numeral 1, though the "correct" type for a Church numeral should actually be (a -> a) -> a -> a.

  arising from a use of `print' at <interactive>:1:0-1

It's implicitly using the print function to display the values. Normally this would tell you where in your program the error was found, but in this case it says <interactive>:1:0-1 because the error was caused by an expression in the REPL.

Possible fix:
  add an instance declaration for (Show ((t -> t1) -> t -> t1))

This is just suggesting that you could fix the error by defining the instance it was expecting.


Now, you probably want to actually print your Church numerals, not just know why you can't. Unfortunately, this isn't as simple as adding the instance it asked for: If you write an instance for (a -> a) -> a -> a, Haskell interprets this as an instance for any specific a, whereas the correct interpretation of a Church numeral is a polymorphic function that works on any arbitrary a.

In other words, you want your show function to be something like this:

showChurch n = show $ n (+1) 0

If you really want to, you may implement the Show instance like this:

instance (Show a, Num a) => Show ((a -> a) -> a -> a) where
    show n = show $ n (+1) 0

and add {-#LANGUAGE FlexibleInstances#-} to the first line of the file. Or you may implement something similar to convert them to a regular number

> churchToInt c1
1
> showChurch c1
"1"

etc.




回答2:


EDIT: Spoiler Alert, as mentioned in the comment

Or, you could have a type for Church numerals, something like this:

data Church x = Church ((x -> x) -> x -> x)

zero :: Church x
zero = Church (\f x -> x)

-- Hack to not clash with the standard succ
succ_ :: Church x -> Church x
succ_ (Church n) = Church (\f x -> (f (n f x)))

instance (Num x) => Show (Church x) where
  show (Church f) = show $ f (1 +) 0


来源:https://stackoverflow.com/questions/6462749/church-numerals-in-haskell

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!