Re: [Haskell-cafe] Newbie: Is ‘type’ synonym hiding two much?
On Thu, Mar 22, 2007 at 06:13:00PM +0300, Dmitri O.Kondratiev wrote: F :: a - b - c Is the same as: F :: a - (b - c) Correcting the typo (use f, not F), these mean the same thing. And means either: -a function 'f' of one argument of type 'a' that returns a function of type (b - c), or it can also be interpreted as: -a function 'f' of two arguments of type 'a' and 'b' returning value of type 'c' Yes. The essential point to understand that these interpretations *are the same*. Now, in the 17.5 section of a book one may see the following declarations: succeed :: b - Parse a b *Before looking at 'succeed' function definition* one may think that 'succeed' is a function of *one* argument of type 'b' that returns object of type 'Parse a b'. That's what it is. However, without looking at the definition of Parse a b, you can't tell whether that is a function or not, and therefore all you can say about succeed is that it takes *at least* one argument. Then I do this substitution *myself as a Haskell runtime* and get in the result the following declaration of a * real function that Haskell runtime* works with: I'm not sure why you feel the need to talk about runtime. This all happens at compile time. 2. Should I search through main and imported modules for treacherous 'type' constructs? They are not treacherous. But yes, if you want to know what a type stands for, you need to look it up. The treacherous thing here is that in Haskell, returning a function is the same as taking one more parameter. This may feel strange at first, but it is a very important idiom and you do need to learn to live with it if you want to use Haskell. 3. Where, in this case goes implementation abstraction principle? Why I must provide *all* the details about function argument type structure in order to understand how this function works? type is just notational convenience. If you want abstraction, use newtype or data. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Newbie: Is ‘type’ synonym hiding two much?
On Thu, Mar 22, 2007 at 06:13:00PM +0300, Dmitri O.Kondratiev wrote: succeed :: b - Parse a b *Before looking at 'succeed' function definition* one may think that 'succeed' is a function of *one* argument of type 'b' that returns object of type 'Parse a b'. Yet, function definition given in the book is: succeed val inp = [(val, inp)] It's common to instead write this as succeed :: b - Parse a b succeed val = \inp - [(val, inp)] so the definition fits the type signature better. 1. Should I work every time as a macro translator when I just see *!any!* function declaration? If you are going to be dealing with the actual definitions of something like Parser then you do need to know what the synonym is, yes. Your implementation should be able to help you, e.g. in ghci: Prelude :i ReadS type ReadS a = String - [(a, String)] -- Defined in Text.ParserCombinators.ReadP The main advantage of the synonym is when you are /using/ the Parser library, so you can put Parser String's in sequence etc without needing to know that internally they're implemented as a function. 2. Should I search through main and imported modules for treacherous 'type' constructs? 3. Where, in this case goes implementation abstraction principle? Why I must provide *all* the details about function argument type structure in order to understand how this function works? If you want abstraction then you need to use newtype or data to declare the type. e.g. if you had newtype Parser a b = Parser (a - [(b, [a])]) then succeed :: b - Parse a b succeed val inp = ... would be rejected by the compiler. Instead you would have to write succeed :: b - Parse a b succeed val = Parser (\inp - ...) Thanks Ian ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Newbie: Is 'type' synonym hiding two much?
Now, in the 17.5 section of a book one may see the following declarations: succeed :: b - Parse a b *Before looking at 'succeed' function definition* one may think that 'succeed' is a function of *one* argument of type 'b' that returns object of type 'Parse a b'. Antti-Juhani Kaijanaho wrote That's what it is. However, without looking at the definition of Parse a b, you can't tell whether that is a function or not, and therefore all you can say about succeed is that it takes *at least* one argument. /Antti-Juhani Kaijanaho wrote At least something to know :) I'll try to remeber this idiom. Then I do this substitution *myself as a Haskell runtime* and get in the result the following declaration of a * real function that Haskell runtime* works with: Antti-Juhani Kaijanaho wrote I'm not sure why you feel the need to talk about runtime. This all happens at compile time. /Antti-Juhani Kaijanaho wrote I wrote runtime because I didn't know how in own word to term inteprepter (GHCi) and compiler (GHC). Both of them will deal with this task/ 2. Should I search through main and imported modules for treacherous 'type' constructs? Antti-Juhani Kaijanaho wrote They are not treacherous. But yes, if you want to know what a type stands for, you need to look it up. The treacherous thing here is that in Haskell, returning a function is the same as taking one more parameter. This may feel strange at first, but it is a very important idiom and you do need to learn to live with it if you want to use Haskell. /Antti-Juhani Kaijanaho wrote I see now, got it! Thanks. succeed :: b - Parse a b *Before looking at 'succeed' function definition* one may think that 'succeed' is a function of *one* argument of type 'b' that returns object of type 'Parse a b'. Yet, function definition given in the book is: succeed val inp = [(val, inp)] Ian Lynagh wrote It's common to instead write this as succeed :: b - Parse a b succeed val = \inp - [(val, inp)] so the definition fits the type signature better. /Ian Lynagh wrote Yes, that make more sense to me - function that returns a customized function Ian Lynagh wrote The main advantage of the synonym is when you are /using/ the Parser library, so you can put Parser String's in sequence etc without needing to know that internally they're implemented as a function. /Ian Lynagh wrote Do you mean that if insted of type sysnonym I would use ADT built with 'data': data Parser a b = Parser (a - [(b, [a])]) succeed :: b - Parse a b succeed val = Parser (\inp - ...) then I would not be able to put put Parser String's in sequence etc without needing to know that internally they're implemented as a function ? Anyway, I will try to implement this version of Parser as well. Bernie Pope wrote I think the main issue here is that from the user's perspective the Parse type should be (or is) abstract. Users of Parse should not really have to know how it is internally implemented. But implementors of Parse will (of course) be concerned with those details. How you look at the Parse type depends on which camp you belong to: implementor or user. /Bernie Pope wrote Very good observation Bernie, thanks. Yet I need to play more with Parser type to justify it for this case :) Thanks guys for all your feedback! It really helps! ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe