Hacker News new | past | comments | ask | show | jobs | submit login

As far as I can tell, however, the article gives no examples of this. All the functions that are written are based on "read" and "mempty" and similar. I'm having issues understanding how to write these functions "from scratch".



* define a typeclass with a function generic in its output

* implement the typeclass for relevant types

* invoke the typeclass function in disambiguated contexts

    class Zero z where
      zero :: z

    instance Zero Int where
      zero = 0

    instance Zero Float where
      zero = 0.0

    instance Zero [a] where
      zero = []
example usage:

    let v :: Int; v = zero
or

    let v = zero :: Int
or pass it to something which expects an Int, disambiguating it, e.g.

    > Data.Char.chr zero
    '\NUL'


You can browse the Haskell sources to find Haskell implementations of them.

Here is the implementation for mempty for the "Sum" type family mentioned in the article:

    mempty = Sum 0
https://github.com/ghc/ghc/blob/d987f71aa3200ce0c94bc57c43b4...

And here it is for lists:

    mempty = []
https://github.com/ghc/ghc/blob/d987f71aa3200ce0c94bc57c43b4...

It's harder for "read" because there is a tangle of auxiliary functions. But for Int, for example, it's essentially the same function you would call "atoi" in C: A function that converts a string like "-123" into the integer -123, or signals an error if the input string is not valid.

But I think there may be a very important misunderstanding here. Neither you nor Haskell define THE read function. If you define a new type, you can define a new read function for this type. So if you define some type MyOwnT, you will define a read function of the concrete type "read :: String -> MyOwnT".

Nobody ever defines a "master" generic function "read :: String -> a" that can return any type! There are many concrete read functions, and the compiler chooses, based on type inference and type hints and sometimes type information at runtime, which concrete one to use at that particular call site.

Again: There is no single magic function that knows how to fabricate an instance of any type from a string. There is only a family of non-magic functions that each know how to fabricate an instance of a specific type.


The interfaces are defined at the modules Text.Read and Data.Monoid, in the standard library. You just take the interface there and implement it. For example, the Maybe instance of Monoid is something like:

    instance Monoid Maybe where
        mempty = Nothing
        mappend Nothing b = b
        mappend a _ = a
Read is bit hard to implement. But it's also not something out of this world.




Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: