zwirn-0.1.0.0: src/Zwirn/Language/Evaluate/Convert.hs
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}
{-# OPTIONS_GHC -Wno-orphans #-}
{-# OPTIONS_GHC -Wno-unused-top-binds #-}
module Zwirn.Language.Evaluate.Convert where
{-
Convert.hs - convert from and to Expressions
Copyright (C) 2023, Martin Gius
This library is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this library. If not, see <http://www.gnu.org/licenses/>.
-}
import qualified Data.Map as Map
import Data.String (IsString, fromString)
import Data.Text (Text, pack)
import Zwirn.Core.Time (Time (..))
import Zwirn.Core.Types
import Zwirn.Language.Evaluate.Expression
fromZwirn :: Zwirn Expression -> Expression
fromZwirn = EZwirn
toZwirn :: Expression -> Zwirn Expression
toZwirn (EZwirn x) = x
toZwirn _ = silence
class FromExpression a where
fromExp :: Expression -> Zwirn a
class ToExpression a where
toExp :: a -> Expression
instance FromExpression Time where
fromExp (EZwirn tz) = fmap (\(ENum t) -> Time (toRational t) 0) tz
fromExp _ = silence
instance FromExpression Double where
fromExp (EZwirn tz) = fmap (\(ENum t) -> t) tz
fromExp _ = silence
instance FromExpression Int where
fromExp (EZwirn tz) = fmap (\(ENum t) -> floor t) tz
fromExp _ = silence
instance FromExpression Expression where
fromExp (EZwirn z) = z
fromExp _ = silence
instance FromExpression Text where
fromExp (EZwirn z) = fmap (\(EText t) -> t) z
fromExp _ = silence
instance FromExpression Bool where
fromExp (EZwirn z) = fmap (\(ENum x) -> x >= 1) z
fromExp _ = silence
instance FromExpression ExpressionMap where
fromExp (EZwirn z) = fmap (\(EMap m) -> m) z
fromExp _ = silence
instance (ToExpression a, FromExpression b) => FromExpression (Zwirn a -> Zwirn b) where
fromExp (EZwirn z) = fmap (\(ELam f) -> fromExp . f . toExp) z
fromExp _ = silence
instance (FromExpression a) => FromExpression (Zwirn a) where
fromExp (EZwirn z) = fmap fromExp z
fromExp _ = silence
instance ToExpression Expression where
toExp = id
instance ToExpression Double where
toExp = ENum
instance ToExpression Time where
toExp (Time t _) = ENum $ fromRational t
instance ToExpression Int where
toExp i = ENum $ fromIntegral i
instance ToExpression Bool where
toExp True = ENum 1
toExp False = ENum 0
instance ToExpression Text where
toExp = EText
instance (ToExpression a) => ToExpression (Map.Map Text a) where
toExp m = EMap $ toExp <$> m
instance (ToExpression a) => ToExpression (Zwirn a) where
toExp a = EZwirn $ fmap toExp a
instance (FromExpression a, ToExpression b) => ToExpression (Zwirn a -> b) where
toExp f = lambda $ \x -> toExp $ f (fromExp x)
instance Num Expression where
(+) = pervasive2 ((+) @Double)
(*) = pervasive2 ((*) @Double)
abs = pervasive (abs @Double)
signum = pervasive (signum @Double)
fromInteger i = ENum $ fromInteger i
negate = pervasive (negate @Double)
instance Fractional Expression where
fromRational r = ENum $ fromRational r
(/) = pervasive2 ((/) @Double)
instance Floating Expression where
pi = EZwirn $ pure $ ENum pi
exp = pervasive (exp :: Double -> Double)
log = pervasive (log :: Double -> Double)
sin = pervasive (sin :: Double -> Double)
cos = pervasive (cos :: Double -> Double)
asin = pervasive (asin :: Double -> Double)
acos = pervasive (acos :: Double -> Double)
atan = pervasive (atan :: Double -> Double)
sinh = pervasive (sinh :: Double -> Double)
cosh = pervasive (cosh :: Double -> Double)
asinh = pervasive (asinh :: Double -> Double)
acosh = pervasive (acosh :: Double -> Double)
atanh = pervasive (atanh :: Double -> Double)
instance IsString Expression where
fromString = EText . pack
class Pervasive a where
pervasive :: (a -> a) -> Expression -> Expression
pervasive2 :: (a -> a -> a) -> Expression -> Expression -> Expression
instance Pervasive Double where
pervasive f (ENum d) = ENum $ f d
pervasive f (EMap m) = EMap $ fmap (pervasive f) m
pervasive _ e = e
pervasive2 f (ENum d) (ENum e) = ENum $ f d e
pervasive2 f (EMap m) (EMap n) = EMap $ Map.unionWith (pervasive2 f) m n
pervasive2 _ e _ = e
instance Pervasive Bool where
pervasive f (ENum d) = toExp $ f (d >= 1)
pervasive f (EMap m) = EMap $ fmap (pervasive f) m
pervasive _ e = e
pervasive2 f (ENum d) (ENum e) = toExp $ f (d >= 1) (e >= 1)
pervasive2 f (EMap m) (EMap n) = EMap $ Map.unionWith (pervasive2 f) m n
pervasive2 _ e _ = e
instance Pervasive Text where
pervasive f (EText d) = EText $ f d
pervasive f (EMap m) = EMap $ fmap (pervasive f) m
pervasive _ e = e
pervasive2 f (EText d) (EText e) = EText $ f d e
pervasive2 f (EMap m) (EMap n) = EMap $ Map.unionWith (pervasive2 f) m n
pervasive2 _ e _ = e
instance Pervasive (Either Double Text) where
pervasive f (EText d) = EText $ (\(Right t) -> t) $ f (Right d)
pervasive f (ENum d) = ENum $ (\(Left t) -> t) $ f (Left d)
pervasive f (EMap m) = EMap $ fmap (pervasive f) m
pervasive _ e = e
pervasive2 f (EText d) (EText e) = EText $ (\(Right t) -> t) $ f (Right d) (Right e)
pervasive2 f (ENum d) (ENum e) = ENum $ (\(Left t) -> t) $ f (Left d) (Left e)
pervasive2 f (EMap m) (EMap n) = EMap $ Map.unionWith (pervasive2 f) m n
pervasive2 _ e _ = e