4

for a homework assignment, a subtask is to make the arithmetic functions (+), (-), (*) and div showable.

We're solved the rest of the assignment, but we're stuck here. Right now we're using the solution to this question here to distinguish between the operations:

showOp op = case op 3 3 of
          6 -> "plus"
          0 -> "minus"
          9 -> "times"
          1 -> "divide"
          _ -> "undefined"

However, this strikes me as kind of ugly as things like showOp (\a b -> a * 3 - y) yield "plus".

Is there any way to better distinguish between the operators?

We are using winhugs atm with the appropriate switches -98 +o in order to be able to use the needed extensions.

Edit: As requested, the actual assignment has to do with Arrays (specifically Array Int (Int -> Int -> Int)). It has to do with generating arrays of operators that fulfill certain conditions.

The assignment states:

Make the data type Array Int (Int->Int-Int) an Instance of Show. The arithmetic operations from the previous exercises should be represented as "plus", "minus", "times" and "div".

thx for any help in advance

5
  • I would be nice to see some more context from the assignment, because making functions themselves showable seems like a strange requirement for homework. Commented May 3, 2013 at 9:13
  • 1
    If the requirement is explicitly for Int->Int->Int, there is little better you can do than such a heuristic unsafe case table. (It would be possible to make it much nicer if general (Num a) => a->a->a was allowed...) Commented May 3, 2013 at 9:34
  • I think that is as good as you are going to see--I think it is absolutely impossible to check equality for functions, which means that you need to check for operational equivalence. You could expand the range of tests to catch more undefined functions, but not much more. Commented May 3, 2013 at 15:35
  • 2
    @isturdy: You could check functions of type Int -> Int -> Int for extensional equality easily enough. You just need to apply both functions to all possible arguments and check that they produce the same result! It might take a while, though. Commented May 3, 2013 at 16:55
  • True, I forgot that Int is bounded. But I do get somewhat impatient... Commented May 3, 2013 at 18:54

1 Answer 1

2

Use induction :)

{-# LANGUAGE FlexibleInstances #-}

instance Eq (Int-> Int -> Int) where 
  f == g = induce f g where
    base = 1
    n = 2
    induce f g = and [f 1 n' == g 1 n' | n' <- [base, n, n+1]]

instance Show (Int-> Int -> Int) where 
  show a = showOp a where
    showOp op = case lookup op ops of
                  Just a -> a
                  otherwise  -> "undefined"
    ops = [((+),"plus")
          ,((-),"minus")
          ,((*),"times")
          ,(div,"divide")]

Output:

*Main> (\a b -> a * 3 - b) :: (Int->Int->Int)
undefined
Sign up to request clarification or add additional context in comments.

2 Comments

all (==True) is better expressed as all id
@is7s: Or even better, and.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.