shrub/pkg/hs-urbit/lib/Noun.hs

103 lines
2.4 KiB
Haskell
Raw Normal View History

2019-07-02 05:51:26 +03:00
module Noun where
2019-05-10 01:46:54 +03:00
import Prelude hiding (all)
import Control.Applicative
import Control.Monad
import Data.Bits
import GHC.Generics
import Test.QuickCheck.Arbitrary
2019-05-15 04:30:44 +03:00
import Test.QuickCheck.Gen
2019-05-18 02:02:39 +03:00
import Data.Flat hiding (getSize)
2019-06-30 06:05:45 +03:00
import ClassyPrelude (Text, all, unpack)
import Data.Hashable (Hashable)
import Data.List (intercalate)
2019-07-02 05:51:26 +03:00
import Noun.Atom (Atom)
2019-06-30 06:05:45 +03:00
import Data.Typeable (Typeable)
2019-05-10 01:46:54 +03:00
import qualified Control.Monad.Fail as Fail
import qualified Data.Char as C
2019-05-10 01:46:54 +03:00
-- Types -----------------------------------------------------------------------
2019-05-10 01:46:54 +03:00
data Cell = ACell !Noun !Noun
deriving (Eq, Ord)
2019-05-10 01:46:54 +03:00
data Noun
= Atom !Atom
2019-05-10 01:46:54 +03:00
| Cell !Noun !Noun
2019-05-18 02:02:39 +03:00
deriving stock (Eq, Ord, Generic)
2019-06-30 06:05:45 +03:00
deriving anyclass (Flat, Hashable)
2019-05-10 01:46:54 +03:00
data CellIdx = L | R
deriving (Eq, Ord, Show)
2019-05-10 01:46:54 +03:00
type NounPath = [CellIdx]
2019-05-10 01:46:54 +03:00
-- Instances -------------------------------------------------------------------
2019-05-10 01:46:54 +03:00
instance Show Noun where
show (Atom a) = show a
show (Cell x y) = fmtCell (show <$> (x : toTuple y))
2019-05-10 01:46:54 +03:00
where
fmtCell :: [String] -> String
fmtCell xs = "[" <> intercalate " " xs <> "]"
instance Arbitrary Noun where
2019-05-17 09:39:07 +03:00
arbitrary = resize 1000 go
2019-05-15 04:30:44 +03:00
where
2019-05-17 09:39:07 +03:00
dub x = Cell x x
go = do
2019-05-15 04:30:44 +03:00
sz <- getSize
2019-05-18 02:02:39 +03:00
(bit, bat :: Bool) <- arbitrary
2019-05-17 09:39:07 +03:00
case (sz, bit, bat) of
( 0, _, _ ) -> Atom <$> arbitrary
( _, False, _ ) -> Atom <$> arbitrary
( _, True, True ) -> dub <$> arbitrary
( _, True, _ ) -> scale (\x -> x-10) (Cell <$> go <*> go)
-- Predicates ------------------------------------------------------------------
isAtom :: Noun -> Bool
isAtom (Atom _) = True
isAtom (Cell _ _) = False
isCell :: Noun -> Bool
isCell (Atom _) = False
isCell (Cell _ _) = True
-- Tuples ----------------------------------------------------------------------
fromTuple :: [Noun] -> Noun
fromTuple [] = Atom 0
fromTuple [x] = x
fromTuple (x:xs) = Cell x (fromTuple xs)
toTuple :: Noun -> [Noun]
toTuple (Cell x xs) = x : toTuple xs
toTuple atom = [atom]
-- Lists -----------------------------------------------------------------------
fromList :: [Noun] -> Noun
fromList [] = Atom 0
fromList (x:xs) = Cell x (fromList xs)
toList :: Noun -> Maybe [Noun]
toList (Atom 0) = Just []
toList (Atom _) = Nothing
toList (Cell x xs) = (x:) <$> toList xs
2019-05-10 01:46:54 +03:00
example :: Noun
example = fromTuple [Atom 1337, Atom 1338, Atom 0]
2019-05-10 01:46:54 +03:00
exampleIO :: IO ()
exampleIO = do
print example