packages feed

hoop-0.3.0.0: test/List.hs

{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# OPTIONS_GHC -ddump-splices -ddump-to-file #-}

module List where

import Debug.Trace
import Language.MSH

[state|
state MListItem a where
    data val  = error "val" :: a
    data next = Nothing     :: Maybe (MListItem a)

    insertEnd :: MListItem a -> Void
    insertEnd item = do
        switch next $ \x -> case x of
            Nothing  -> next <: Just item
            (Just n) -> next <: Just (object (n.!insertEnd item))
        return ()

    setNext :: Maybe (MListItem a) -> Void
    setNext item = next <: item

    toListItems :: [a]
    toListItems = do
        v <- this.!val
        switch next $ \x -> case x of
            Nothing  -> return [v]
            (Just n) -> do
                let
                    vs = result (n.!toListItems)
                return (v:vs)

state MList a where
    data root = Nothing :: Maybe (MListItem a)

    insert :: a -> Void
    insert val = do
        let
            item = new (val, Nothing)
        switch root $ \x -> case x of
            Nothing  -> root <: Just item
            (Just r) -> do
                this.!root.$insertEnd item
                return ()

    toList :: [a]
    toList = do
        switch root $ \x -> case x of
            Nothing  -> return []
            (Just r) -> return $ result (r.!toListItems)

state SList a : MList a where
    data predicate :: a -> a -> Bool

    --insert :: a -> Void
    insert val = do
        let
            item = new (val, Nothing)
        switch root $ \x -> case x of
            Nothing -> root <: Just item
            Just r  -> do
                p <- this.!predicate
                root <: Just (helper val p r)

state Program where
    data l :: MList Int

    run :: MList Int -> [Int]
    run arg = do
        l <: arg
        this.!l.!insert 23
        this.!l.!insert 16
        this.!l.!insert 42
        this.!l.!insert 24
        r <- this.!l.!toList
        return r
|]

mkItem :: a -> MListItem a
mkItem v = new (v, Nothing)

helper :: a -> (a -> a -> Bool) -> MListItem a -> MListItem a
helper v p i =
    let rv = result (i.!val)
        item = mkItem v
    in if p v rv then case result (i.!next) of
            Nothing -> object (i.!setNext (Just item))
            Just n  -> object (i.!setNext (Just $ helper v p n))
       else object (item.!setNext (Just i))

instance Show (MList Int) where
    show o = show $ result $ o.!toList

test :: MList Int -> [Int]
test l = let
    --l = new Nothing :: MList Int
    a = object (l.!insert 23)
    b = object (a.!insert 16)
    c = object (b.!insert 42)
    d = object (c.!insert 24) in result (d.!toList)

foo :: MListItem Int
foo = new (5, Nothing)

--bar = result $ foo.!insertEnd foo.!toListItems

baz :: Program
baz = new (new Nothing)