Last active
February 21, 2019 15:58
-
-
Save cblp/1954e14f27e8caa4126eb90ad5082fef to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- stack --resolver=lts-13.8 script | |
{-# OPTIONS -Wall -Wno-orphans #-} | |
{-# LANGUAGE FlexibleInstances #-} | |
{-# LANGUAGE LambdaCase #-} | |
{-# LANGUAGE OverloadedStrings #-} | |
{-# LANGUAGE QuasiQuotes #-} | |
import Data.EDN (Tagged (..), TaggedValue, Value (..), renderText) | |
import Data.EDN.QQ (edn) | |
import Data.Text (Text) | |
import qualified Data.Text as Text | |
tvToList :: TaggedValue -> [TaggedValue] | |
tvToList tv = case tv of | |
NoTag v -> go v | |
Tagged _ _ v -> go v | |
where | |
go :: Value -> [TaggedValue] | |
go v = case v of | |
List vs -> vs | |
_ -> error (show v) | |
main :: IO () | |
main = | |
either (fail . Text.unpack) print $ calc [edn| | |
(+ | |
(/ 6 3 2) | |
(* 2 3) | |
(- 4 5)) | |
|] | |
paraOf :: (a -> [a]) -> (a -> [b] -> b) -> a -> b | |
paraOf thisToList f = go where go a = f a $ map go $ thisToList a | |
calc :: TaggedValue -> Either Text Double | |
calc = paraOf tvToList go where | |
go (NoTag v) children = case v of | |
Floating f -> pure f | |
Integer i -> pure $ fromIntegral i | |
List (NoTag (Symbol "" op) : _) -> do | |
checked <- sequence $ drop 1 children | |
case op of | |
"+" -> Right (foldr (+) 0.0 checked) | |
"-" -> Right (foldr (-) 0.0 checked) | |
"*" -> Right (foldr (*) 1.0 checked) | |
"/" -> case checked of | |
-- From the clojure docs: | |
-- If no denominators are supplied, returns 1/numerator, | |
-- else returns numerator divided by all of the denominators. | |
[] -> Left "No arguments given to `/`" | |
[n] -> Right (1 / n) | |
(n : ds) -> Right (foldl (/) n ds) | |
_ -> Left $ "Unknown operation: " <> op | |
_ -> Left $ "unknown " <> renderText (NoTag v) | |
go Tagged{} _ = Left "tagged not supported" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment