3 ms·
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 havin
by hansbo 9y ago
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".
- masklinn 9y ago* 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'
- marcosdumay 9y agoThe 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.
- tom_mellior 9y agoYou 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/d987f71aa3200ce0c94bc57c43b4fcc92eaccf76/libraries/base/Data/Semigroup/Internal.hs#L204 https://github.com/ghc/ghc/blob/d987f71aa3200ce0c94bc57c43b4... And here it is for lists: mempty = [] https://github.com/ghc/ghc/blob/d987f71aa3200ce0c94bc57c43b4fcc92eaccf76/libraries/base/GHC/Base.hs#L303 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.