## Monday, July 12, 2010

Why some program show strange behavior? To answer the question, I should define what is "strange". For example the following behavior is strange.

`// JSvar a = ***, b = ***, c = ***;console.log(a < b); // trueconsole.log(b < c); // trueconsole.log(c < a); // true`

In the case, "strange" means "different from mathematical behavior". Now the answer is clear, it is because those are not purely mathematical objects.

`var a = "9", b = 10, c = "100";console.log(a < b); // trueconsole.log(b < c); // trueconsole.log(c < a); // true`

Haskell also shares some common "strangeness" with other languages.
`Prelude> let x = *****Prelude> x == x + 1True`

You may know the quiz in the other language. This "strangeness" come from the limited resolution of floating point number.
`Prelude> let x = 2 ** 64Prelude> x == x + 1True`

You may disagree. You may see "Multiple declarations of something" error.
But wait. Didn't you have ever defined 'show'? Isn't it overloaded?

Haskell is very different from C++/Java. In C++/Java, you can overload functions whose type of arguments are different. In Haskell, you can also overload functions whose type of return value are different. It is very important.

The quiz's tricks are,

`class Foo t where    a :: t    b :: tinstance Foo Int where    a = 0    b = 1instance Foo Integer where    a = 1    b = 0c :: Intc = 0d :: Integerd = 0main = do  print \$ a + c == 0 -- True.  print \$ a == c     -- True. a::Int == c::Int == 0.  print \$ c == 0     -- True.   print \$ a + d == 1 -- True.   -- d is Integer. So the variable a is a::Integer,   -- which equals 1. "d == 1" is a misconception.  print \$ b + c == 1 -- True. b::Int is 1.  print \$ b + d == 0 -- True. However, b::Integer is 0.  print \$ b == d     -- True. Yes, both are 0::Integer;  print \$ d == 0     -- True.   -- Why I use "d == 0" not "b == 0"?   -- Because it causes "ambiguous type" error.  -- You know, ":t 0" is "(Num t) => t". No way to determine  -- it is Int or Integer.  -- hints to make answer unique (perhaps...)  print \$ sum([a, b, c])  -- 1: It is [0, 1, 0]::[Int]  print \$ sum([a, b, d])  -- 1: It is [1, 0, 0]::[Integer]  print \$ [a, b, c] !! a  -- 0: (!!) take Int argument,  print \$ [a, b, c] !! b  -- 1: so it says (a::Int /= b::Int)  print \$ [a, b, c] !! c  -- 0  -- Why I didn't show [a, b, c] !! d is,   -- it causes error because d is Integer.`