module Pointfree where

import Plugin.Pl.Common (mapTopLevel, mapTopLevel')
import Plugin.Pl.Optimize (optimize)
import Plugin.Pl.Parser (parsePF)
import Plugin.Pl.PrettyPrinter (prettyTopLevel)
import Plugin.Pl.Transform (transform)

import Data.Maybe (listToMaybe)

{- |
  >>> pointfree "I'm not a valid Haskell expression!"
  []
  >>> pointfree "sum xs = foldr (+) 0 xs"
  ["sum = id (fix (const (foldr (+) 0)))","sum = fix (const (foldr (+) 0))","sum = foldr (+) 0"]
-}
pointfree :: String -> [String]
pointfree :: String -> [String]
pointfree
  = (String -> [String])
-> (TopLevel -> [String]) -> Either String TopLevel -> [String]
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either
    ([String] -> String -> [String]
forall a b. a -> b -> a
const [])
    ((TopLevel -> String) -> [TopLevel] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map TopLevel -> String
prettyTopLevel ([TopLevel] -> [String])
-> (TopLevel -> [TopLevel]) -> TopLevel -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Expr -> [Expr]) -> TopLevel -> [TopLevel]
forall (f :: * -> *).
Functor f =>
(Expr -> f Expr) -> TopLevel -> f TopLevel
mapTopLevel' Expr -> [Expr]
optimize (TopLevel -> [TopLevel])
-> (TopLevel -> TopLevel) -> TopLevel -> [TopLevel]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Expr -> Expr) -> TopLevel -> TopLevel
mapTopLevel Expr -> Expr
transform)
  (Either String TopLevel -> [String])
-> (String -> Either String TopLevel) -> String -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Either String TopLevel
parsePF

{- |
  >>> pointfree' "I'm not a valid Haskell expression!"
  Nothing
  >>> pointfree' "sum xs = foldr (+) 0 xs"
  Just "sum = foldr (+) 0"
-}
pointfree' :: String -> Maybe String
pointfree' :: String -> Maybe String
pointfree' = [String] -> Maybe String
forall a. [a] -> Maybe a
listToMaybe ([String] -> Maybe String)
-> (String -> [String]) -> String -> Maybe String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> [String]
forall a. [a] -> [a]
reverse ([String] -> [String])
-> (String -> [String]) -> String -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [String]
pointfree