reset password
Author Message
bfazeli
Posts: 6
Posted 17:35 Feb 16, 2019 |

Hi everyone, 

I came across a particular challenge that I hope one of you expert Haskellers can shed some light on.

Suppose that I have a custom type that I can specify a collection to be of and that type can be of two custom types,

how can I then let haskell know that the type of my collection will be of myType w/o it defaulting to one of the built-in types?

I.e. passing state into a fnx where state is some type that has ([MyType], []) and MyType is one of two custom types, IntType or StringType

Much appreciated in advance

Last edited by bfazeli at 17:52 Feb 16, 2019.
rabbott
Posts: 1649
Posted 18:13 Feb 16, 2019 |

You would have to provide more details for me to answer, but read chapter 8 on user-defined types. That may help.

jpatel77
Posts: 44
Posted 18:22 Feb 16, 2019 |

Hi Bijan,

I am bit confused here, what do you mean by types actually? Are IntType and StringType value constructors for MyType? If so, then defining the type annotation for your funx should be okay. I do not see why it would default the value to anything. You could explicitly put this MyType (i.e. a type) at the type annotations, and then handle each case (i.e. value constructor) inside the function. I might be totally off the point though without much information.

Last edited by jpatel77 at 18:24 Feb 16, 2019.
bfazeli
Posts: 6
Posted 18:54 Feb 16, 2019 |

Thank you gentlemen for diving further and expanding on my question.

I was able to figure it out, the types had to be explicit as to what you pass into a collection of a custom type.

i.e. Haskell CAN'T infer [MyType 8, MyType "fib"] but CAN infer [IntType 8, StringType "fib"] even though the data MyType is of either type IntType or StringType. Seems as though Haskell always wants the most explicit type which is interesting because I would think during compile time Haskell can interpret that MyType is of two types and will proceed to check which of the two types an integer or a string will fall under when it's explicitly declared but it doesn't, I guess Haskell isn't truly lazy :p

The book doesn't go into this but I managed to figure it out.

rabbott
Posts: 1649
Posted 20:05 Feb 16, 2019 |

Would you mind posting the actual code that you are talking about along with your comments about the code. Without seeing the actual code, it's hard for me to understand the point you are making.

jpatel77
Posts: 44
Posted 20:43 Feb 16, 2019 |
bfazeli wrote:

Thank you gentlemen for diving further and expanding on my question.

I was able to figure it out, the types had to be explicit as to what you pass into a collection of a custom type.

i.e. Haskell CAN'T infer [MyType 8, MyType "fib"] but CAN infer [IntType 8, StringType "fib"] even though the data MyType is of either type IntType or StringType. Seems as though Haskell always wants the most explicit type which is interesting because I would think during compile time Haskell can interpret that MyType is of two types and will proceed to check which of the two types an integer or a string will fall under when it's explicitly declared but it doesn't, I guess Haskell isn't truly lazy :p

The book doesn't go into this but I managed to figure it out.

Good to know that you managed to figure it out.

Actually Haskell types and their values are quite different than any other languages. Thus, we can not expect IntType to be interpreted dynamically as a subtype of MyType. In fact, IntType is not a type at all. It is (along with the parameter) just a value out of all the possible values of MyType. Just like 2 or 3 or 4 are the values of a type int. Therefore, you have to be explicit about what value (i.e. IntType _ or StringType _) of a type (MyType in your case) you desire to pass. At the receiver function, we can consume this variation with the expectation that it would be of MyType type, and then handle them for each possible values (or functions as in your case) separately.

This is somewhat similar to the Interface in Java. That is, given a function compare(Comparable obj1, Comparable obj2) where Comparable is an interface, we cannot make a call as compare(new Comparable(), new Comparable()). However, what we can do is, pass on those objects that implement Comparable interface OR add the required implementation during the instantiation at the method call itself. In both the cases, what we are doing is passing on a value (out of all the possible values) of a type Comparable and not the type itself.

You are correct that book didn't cover this scenario, however there is one line where he clarifies the difference between type and the value (or value constructor):

We couldn't write a type declaration of Circle -> Float because Circle is not a type, Shape is.

That is how I understand types in Haskell, hope it will help.

Last edited by jpatel77 at 20:46 Feb 16, 2019.