Brool brool (n.) : a low roar; a deep murmur or humming

Stupid Haskell Tricks

 |  oo stupid tricks haskell coding

Let’s say that you really, really want some notion of objected oriented programming. So let’s make a class that represents a name, and some simple method calls on it:

data S = S { name :: String } deriving (Show)
firstname s = (words (name s))!!0
lastname  s = (words (name s))!!1

But, dammit, you want to invoke it like you would in C++. So define a function:

*Main> let (-->) x f = f x
*Main> let test = S "George Washington"
*Main> test --> firstname
"George"
*Main> test --> lastname
"Washington"

(It’s tempting to use `.`, but it conflicts with the Prelude. Also note that you could define it as “(–>) = flip (\$)“). But what if it takes more than one parameter?

*Main> let flip_concat t s = intercalate t $ reverse.words $ name s
*Main> test --> flip_concat ", "
"Washington, George"
*Main> test --> flip_concat(", ")
"Washington, George"

… although you might not like that anything can be applied to (–>).

*Main> [1,2,3] --> length
3

class Deref a where
    (-->) :: a -> (a -> b) -> b
    x --> f = f x 

instance Deref S

*Main> [1,2,3] --> length

:1:0:
    No instance for (Deref [t])
      arising from a use of `-->' at :1:0-17
    Possible fix: add an instance declaration for (Deref [t])
    In the expression: [1, 2, 3] --> length
    In the definition of `it': it = [1, 2, 3] --> length

You can even use tuple passing to make it look even more like a typical call.

*Main> let pretty (pre, mid, post) s = pre ++ (firstname s) ++ mid ++ (lastname s) ++ post
*Main> test --> pretty ("<", ", ", ">")
""

… although that makes it harder to curry.

Discussion

Comments are moderated whenever I remember that I have a blog.

Joshua | 2012-05-05 17:10:15
How would you curry while tuple-passing? It sounds more than just difficult.
Reply
Add a comment