Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon. Entire thread

Calm me down, /prog/.

Name: Anonymous 2012-02-25 22:49

Monads make me want to die.

;-;

Name: Anonymous 2012-02-25 22:52

SHOOOOOOOOSSSSSHHHHHH.

PAP.

Name: Anonymous 2012-02-25 22:55

concat cannot into IO String
compile cannot into String
return does IO
must IO
inconvenient
too many levels
deeper IO
do not want
;-;

Name: Anonymous 2012-02-25 23:27

Applicative functors are better.

Name: Anonymous 2012-02-25 23:29

>>1
It's alright, >>1-kun. Just remember that they are but a Typeclass, and that you don't truly need to ``understand'' them, just get used to them. Read up on parametric polymorphism first (ADTs, how they are parametric) and probably functors a bit (you map and shuffle concrete types of a container around). It helps  in clearing things up.

But you must know the gist of monads already. It's mostly container type shuffling, shoving contained things into containers and non-contained things into the container.

Name: Anonymous 2012-02-26 0:25

>>5
I know how they work

But fuck they get in the way.
Fuck sake.
I just wanted to parse Lisp and they taint everything in every function and everything must bend over to IO. For fuck sake. Fuck haskell. If Erlang had tagged unions like Haskell, I would write in nothing else, But no, it merely has shitty records. Fuck. I'm going back to C.

Name: Anonymous 2012-02-26 0:26

Haskell: Best Practices in Enterprise Software Development

Name: Anonymous 2012-02-26 1:28

>>6
I just wanted to parse Lisp and they taint everything in every function and everything must bend over to IO.
Post some code, because I'm pretty sure you're designing your program wrong.

Name: Anonymous 2012-02-26 1:56

>>8
Haskell: where every design is wrong.

Name: Anonymous 2012-02-26 2:11

>>11
Nice doubles, oniichan.

Name: Anonymous 2012-02-26 2:26

I just wanted to parse Lisp
So you're using really bad shit to parse slightly less bad shit?

Name: Anonymous 2012-02-26 2:28

Now that I think about it, how exactly do you parse Lisp with only a handful of Fibs and Fact implementations?

Name: Anonymous 2012-02-26 2:33

>>12
I guess you have a broken date-time implementation at your disposal as well, I saw a Haskell programmer brag about that once.

Name: Anonymous 2012-02-26 2:46

>>12,13
And oh my god how I could forget, you probably have a couple of quicksort implementations as well don't you? It's amazing what Haskell can be used for isn't it?

Name: Anonymous 2012-02-26 11:47

hurr durr haskal is hrd

--
-- Lisp.hs
--

module Lisp where

import Control.Applicative
import Data.Char

data SExpr = Number Int
           | Symbol String
           | Cons SExpr SExpr
             deriving (Show)

newtype Parse a = Parse { runParse :: [String] -> [(a, [String])] }

instance Alternative Parse where
  p1 <|> p2 = Parse $ \ts -> runParse p1 ts ++ runParse p2 ts
  empty     = Parse $ const []

instance Applicative Parse where
  p1 <*> p2 = Parse $ \ts -> do (f,ts') <- runParse p1 ts
                                (x,ts'') <- runParse p2 ts'
                                return (f x, ts'')
  pure x    = Parse $ \ts -> [(x,ts)]

instance Functor Parse where
  fmap f p = Parse $ \ts -> do (x,ts') <- runParse p ts
                               return (f x, ts')

nil :: SExpr
nil = Symbol "nil"

isIDChar :: Char -> Bool
isIDChar c = isAlphaNum c || c `elem` "+-*/<>!?"

tokens :: String -> [String]
tokens cs'@(c:cs)
  | c == ';'   = tokens $ dropWhile (/= '\n') cs
  | isSpace c  = tokens cs
  | isDigit c  = takeToken isDigit
  | isIDChar c = takeToken isIDChar
  | otherwise  = [c] : tokens cs
  where takeToken f = let (t,cs'') = span f cs' in t : tokens cs''
tokens _ = []

pDottedList :: Parse SExpr
pDottedList = mkList <$> pPar ((,) <$> pOneOrMore pExpr <* pLit "." <*> pExpr)
  where mkList (xs,x) = foldr Cons x xs

pExpr :: Parse SExpr
pExpr = pDottedList <|> pList <|> pNumber <|> pQuote <|> pSymbol

pList :: Parse SExpr
pList = foldr Cons nil <$> pPar (pZeroOrMore pExpr)

pLit :: String -> Parse String
pLit s = pSat (== s)

pNumber :: Parse SExpr
pNumber = Number <$> read <$> pSat (all isDigit)

pOneOrMore :: Parse a -> Parse [a]
pOneOrMore p = (:) <$> p <*> pZeroOrMore p

pPar :: Parse a -> Parse a
pPar p = pLit "(" *> p <* pLit ")"

pQuote :: Parse SExpr
pQuote = mkQuote <$ pLit "'" <*> pExpr
  where mkQuote e = Cons (Symbol "quote") (Cons e nil)

pSat :: (String -> Bool) -> Parse String
pSat f = Parse $ \ts ->
  case ts of
    t:ts' | f t -> [(t,ts')]
    _           -> []

pSymbol :: Parse SExpr
pSymbol = Symbol <$> pSat (all isIDChar)

pZeroOrMore :: Parse a -> Parse [a]
pZeroOrMore p = pOneOrMore p <|> pure []

parse :: String -> SExpr
parse = fst . head . filter (null . snd) . runParse pExpr . tokens


And not an IO monad in sight. It would be a lot shorter if I would just learn Parsec or something, but I'm too lazy.

Name: Anonymous 2012-02-26 14:43

>>15
you are halfway there already (of learning parsec)

Name: Anonymous 2012-02-26 16:34

>>16
I looked at it once and I don't like how each parser can only return one result, and how you need to use try to keep parsers from consuming input if they don't match completely. I like my way (which is based off the parser in Implementing Functional Languages) better.

Newer Posts
Don't change these.
Name: Email:
Entire Thread Thread List