Tagging functions in Haskell - haskell

An elementary Haskell question:
I would like to "tag functions" in Haskell: I have a list
scheme = [ f1, f2, f3, ... ]
which is built from some simple functions, some of them belonging to a certain group:
f1 :: a -> a
f1 a = ...
f2 :: a -> a -- "belongs to group"
f2 a = ...
f3 :: a -> a
f3 a = ...
f4 :: a -> a -- "belongs to group"
f4 a = ...
...
I want to create a smaller list, containing only the functions belonging to that subgroup:
filter belongsToGroup scheme
In Java, the functions would be subclasses of a Function class, some of them implementing an empty tagging interface FunctionGroup. The filter function could then be realized with the operator instanceof
I tried to understand how I could mimic this behaviour in Haskell (studying "type classes"), but had no success.
Any help?

Haskell actively discourages you from using type system escape hatches. (An instanceof-like construct would break some nice type system properties such as parametricity.) You most likely want to use this type:
type TaggedFunction a b = (a -> b, Bool)
Where first component is just the regular function you want to use, and the second component is True when the function belongs to the group, or False otherwise.
Then you filter TaggedFunctions like this: filter snd tfs

One approach to this problem would be to create a data type representing these functions.
data TaggedFunction a = UsefulFunction (a -> a)
| UselessFunction (a -> a)
f1 :: TaggedFunction a
f1 = UsefulFunction $ \x -> x
f2 :: TaggedFunction a
f2 = UselessFunction $ \x -> x
isUseful :: TaggedFunction a -> Bool
isUseful (UsefulFunction _) = True
isUseful _ = False
main :: IO ()
main = do
let fs = [f1, f2, f1, f2]
useful = filter isUseful fs
print $ (_f $ head useful) 4
This method is easily expandable to include more than two groups, and could even be automatically generated with e.g. Template Haskell.
Edit
After a bit of playing around, I like this refactor of TaggedFunction better.
data TaggedFunction a = Group1 { _f :: a }
| Group2 { _f :: a }
| Group3 { _f :: a }
f1 :: TaggedFunction (a -> a)
f1 = Group1 $ \x -> x
f2 :: TaggedFunction (a -> a)
f2 = Group2 $ \x -> x
isGroup :: Int -> TaggedFunction a -> Bool
isGroup 1 (Group1 _) = True
isGroup 2 (Group2 _) = True
isGroup 3 (Group3 _) = True
isGroup _ _ = False
main :: IO ()
main = do
let fs = [f1, f2, f1, f2]
useful = filter (isGroup 1) fs
print $ length useful
print $ (_f $ head useful) 4
Output:
λ> main
2
4
Note that isGroup is now not total (which I don't like), but it was more convenient than individual isGroupN functions for the purposes of this example.

Related

Simulating non-deterministic choice through the List Monad

I'm trying to write an evaluation function for a language that I am working on in which non-determinism can be permitted within an if-block, called a selection block. What I'm trying to achieve is the ability to pick an if/selection statement from the block whose guard is true and evaluate it but it doesn't matter which one I pick.
From searching, I found an example that performs in a similar way to what I would like to achieve through modelling coinflips. Below is my adapation of it but I'm having issue in applying this logic to my problem.
import Control.Monad
data BranchType = Valid | Invalid deriving (Show)
data Branch = If (Bool, Integer) deriving (Show, Eq)
f Valid = [If (True, 1)]
f Invalid = [If (False, 0)]
pick = [Invalid, Invalid, Valid, Invalid, Valid]
experiment = do
b <- pick
r <- f b
guard $ fstB r
return r
s = take 1 experiment
fstB :: Branch -> Bool
fstB (If (cond, int)) = cond
main :: IO ()
main = putStrLn $ show $ s -- shows first branch which could be taken.
Below is my ADT and what I have been trying to make work:
data HStatement
= Eval HVal
| Print HVal
| Skip String
| Do HVal [HStatement]
| If (HVal, [HStatement])
| IfBlock [HStatement] -- made up of many If
| Select [HStatement] -- made up of many If
deriving (Eq, Read)
fstIf :: HStatement -> Bool
fstIf (If (cond, body)) = if hval2bool cond == True
then True
else False
h :: Env -> HStatement -> IOThrowsError ()
h env sb = do
x <- g env sb
guard $ fstIf x -- Couldn't match expected type ‘HStatement’ with actual type ‘[HStatement]’
-- after guard, take 1 x then evaluate
g :: Env -> HStatement -> IOThrowsError [HStatement]
g env (Select sb) = mapM (\x -> f env x) sb
f :: Env -> HStatement -> IOThrowsError HStatement
f env (If (cond, body)) = evalHVal env cond >>= \x -> case x of
Bool True -> return $ If (Bool True, body)
Bool False -> return $ If (Bool False, body)
The error I receive is the following : Couldn't match expected type ‘HStatement’ with actual type ‘[HStatement]’ at the guard line. I believe the reason as to why the first section of code was successful was because the values were being drawn from List but in the second case although they're being drawn from a list, they're being drawn from a [HStatement], not something that just represents a list...if that makes any sort of sense, I feel like I'm missing the vocabulary.
In essence then what should occur is given a selection block of n statement, a subset of these are produced whose guards are true and only one statement is taken from it.
The error message is pretty clear now that you have some types written down. g returns IOThrowsError [HStatement], so when you bind its result to x in h, you have an [HStatement]. You then call fstIf, which expects a single HStatement, not a list. You need to decide how to handle the multiple results from g.

How to create a Haskell data structure containing polyvariadic functions?

How should I type and implement run, so that the following statements work ?
data Run = Run {run :: ??}
f1 = Run (\x -> x)
f2 = Run (\x y-> x+y)
f3 = Run (\x y z -> x*(y+z))
print $ run f1 1 :: Int --> 1
print $ run f2 1 2 :: Int --> 3
print $ run f3 1 2 3 :: Int -> 5
All the polyvariadic functions in Run are of type Int -> ... -> Int: they take a variable number of Int arguments and yield a Int.
If it's any easier, I could live with a solution having a maximum number of arguments, e.g. 3:
data Run
= Run1 (Int -> Int)
| Run2 (Int -> Int -> Int)
| Run3 (Int -> Int -> Int -> Int)
f1 = Run1 (\x -> x)
f2 = Run2 (\x y-> x+y)
f3 = Run3 (\x y z -> x*(y+z))
How would you implement run ?
Since both f1 and f2 in your code have the same type Run, the type checker can not distinguish between run f1 and run f2 which must have the same type.
This makes it hard to implement variadic functions properly.
It's much easier to use instead
data Run a = Run { run :: a }
so that f1 and f2 no longer share the same type.
If you only care about functions Int -> ... -> Int there might be some solutions using type families, GADTs, DataKinds, and the like. This may be overkill, though, depending on what you are trying to realize.

What are the common uses of type classes?

I'm going through type classes using this resource, I've come up with two uses:
a) Enabling functions to take different types without having to redefine the function interface:
class MyClass a where
myFunc :: a -> Bool
instance MyClass Int where
myFunc 1 = False
myFunc x = intFunction x
instance MyClass String where
myFunc "hello" = False
myFunc y = stringFunction
intFunction :: a -> Bool
intFunction i
| i > 100 = True
| otherwise = False
stringFunction :: a -> Bool
stringFunction s
| length s > 10 = False
| otherwise = True
b) Importing functionality into polymorphic functions:
class Operator a b where
(^&) :: a -> b -> Bool
instance Operator a b where
"hello" ^& 0 = True
x ^& y = False
exampleFunc :: (Operator a b) => a -> b -> Bool
exampleFunc e1 e2 = e1 ^& e2
Questions:
1) What are the other uses of type classes in Haskell?
2) How are type classes generally used in large programs?
N.B Apologies if this is a very broad question, I'm just trying to get a feel as to how I can structure my programs around type classes

GetOpt usage and foldl, flip, id

In the second example given in the documentation for System.Console.GetOpt, reproduced here, I am unable to understand or unpack this line:
(o,n,[] ) -> return (foldl (flip id) defaultOptions o, n)
What is this foldl doing, and how does it achieve it? What is the purpose of (flip id)? What is going on?
Code:
import System.Console.GetOpt
import Data.Maybe ( fromMaybe )
data Options = Options
{ optVerbose :: Bool
, optShowVersion :: Bool
, optOutput :: Maybe FilePath
, optInput :: Maybe FilePath
, optLibDirs :: [FilePath]
} deriving Show
defaultOptions = Options
{ optVerbose = False
, optShowVersion = False
, optOutput = Nothing
, optInput = Nothing
, optLibDirs = []
}
options :: [OptDescr (Options -> Options)]
options =
[ Option ['v'] ["verbose"]
(NoArg (\ opts -> opts { optVerbose = True }))
"chatty output on stderr"
, Option ['V','?'] ["version"]
(NoArg (\ opts -> opts { optShowVersion = True }))
"show version number"
, Option ['o'] ["output"]
(OptArg ((\ f opts -> opts { optOutput = Just f }) . fromMaybe "output")
"FILE")
"output FILE"
, Option ['c'] []
(OptArg ((\ f opts -> opts { optInput = Just f }) . fromMaybe "input")
"FILE")
"input FILE"
, Option ['L'] ["libdir"]
(ReqArg (\ d opts -> opts { optLibDirs = optLibDirs opts ++ [d] }) "DIR")
"library directory"
]
compilerOpts :: [String] -> IO (Options, [String])
compilerOpts argv =
case getOpt Permute options argv of
(o,n,[] ) -> return (foldl (flip id) defaultOptions o, n)
(_,_,errs) -> ioError (userError (concat errs ++ usageInfo header options))
where header = "Usage: ic [OPTION...] files..."
The type of flip id is b -> (b -> c) -> c and you could find explanations here: Why does Haskell's "flip id" has this type?
The foldl (flip id) defaultOptions o sub-expression does the following:
Takes defaultOptions as initial value (defaultOptions has type Options)
Takes each element from o (each element has type Options -> Options)
Folds all elements using flip id function (it has b -> (b -> c) -> c type)
Since all of o elements changes corresponding option in the given configuration, the result of the foldl (flip id) defaultOptions o will be a configuration of all parsed options. All missed options replaced with their default values from defaultOptions.
The other parts of (o,n,[] ) -> return (foldl (flip id) defaultOptions o, n) expressions are pretty simple:
(o,n,[] ) -> matches a list of parsed options, a list of non-options and an empty list of errors
return (..., n) just puts the value (..., n) into monad IO (Options, [String])
(This is not strictly an answer to your question, but #soon asked me to post it anyway.)
The semantics of each command-line argument you define is described by
a transition function Options -> Options. Since you can pass many
arguments to a program, you end up with a list of such transition
functions [Options -> Options]. The goal is to compute the sum
effect of these transitions, i.e. an Options -> Options that applies
each transition in turn.
A particularly nice way of achieving this is to observe the structure
of endomorphisms a -> a for any type a:
id :: a -> a is the identity transition function that doesn't actually do anything
Given two transition functions f1, f2 :: a -> a, their composition
f1 . f2 corresponds precisely to applying both, in order. Note
also that this combination is associative, since doing f2 . f3 and
then f1 is the same as doing f3 followed by f1 . f2.
So we have a monoid!
The Haskell standard library base already contains this monoid with
the name Endo.
Using this, we can rewrite
foldl (flip id) defaultOptions o
in a much nicer way that, in my opinion, makes it immediately obvious what's happening here:
appEndo (fold o) defaultOptions
by changing the result type of options to [OptDescr (Endo Options)]; or, if you'd rather not, you can just add the extra Endo
line noise at combination time (by writing appEndo (foldMap Endo o) defaultOptions). Here, fold o :: Endo Options is the composite of all the individual transition functions, and appEndo (fold o) :: Options -> Options is how this resulting transition function is finally applied to the initial Options.
Note that this also works regardless of the data structure used for o: it will work for a list of transition functions, or a tree, or a Maybe, because of the associative property of the monoid at hand; and fold is polymorphic enough to expose this.

Showing the name of a function [duplicate]

Is it possible in Haskell to implement a function which returns its own function name?
A possible type could be (a -> b) -> String.
You want a function that takes a function argument, and returns the definition site variable name that corresponds to the name of that function?
This isn't possibly without meta-programming, which is usually a sign you're doing something wrong :).
But assuming you're not, one way to achieve something in the right direction is via Template Haskell, which can get at unique names (how the compiler names things). E.g.
Prelude Language.Haskell.TH> :set -XTemplateHaskell
Prelude Language.Haskell.TH> let f x y = x + y
Prelude Language.Haskell.TH> $( stringE . show =<< reify 'f )
"VarI f_1627394057
(ForallT [PlainTV a_1627394063]
[ClassP GHC.Num.Num [VarT a_1627394063]]
(AppT (AppT ArrowT (VarT a_1627394063))
(AppT (AppT ArrowT (VarT a_1627394063))
(VarT a_1627394063))))
Nothing (Fixity 9 InfixL)"
And now we know a lot about the variable. So you can play games by passing a Name to the function (via 'f) rather than f itself.
You are certainly in the world of reflection and meta-programming though, so it would help to know more about what you are trying to do.
To clarify something mentioned in dons' post: no functions have names in Haskell. There are bindings which may bind functions, but if I had such a function (call it getName) as you seek then what would you expect this to return:
let f x = x
g = f
h = f
in getName g == getName h
I don't know what you need it for, but maybe a simplistic solution suffices? Like so:
data NamedFunction a b = NamedFunction {
name :: String,
apply :: a -> b
}
timesTwo :: NamedFunction Int Int
timesTwo = NamedFunction "timesTwo" (\x -> 2 * x)
which you can use as follows:
ghci> timesTwo `apply` 7
14
ghci> name timesTwo
"timesTwo"
You can then write your own version of (.):
-- contrast (.) :: (b -> c) -> (a -> b) -> (a -> c)
compose :: NamedFunction b c -> NamedFunction a b -> NamedFunction a c
compose (NamedFunction n1 f1) (NamedFunction n2 f2) =
NamedFunction (n1++ " . " ++ n2) (f1 . f2)
In ghci:
ghci> let f = timesTwo `compose` timesTwo in (f `apply` 7, name f)
(28,"timesTwo . timesTwo")
You'll have to reimplement your own versions of map, filter and so on, and you're bound to run into other problems later, but maybe this is all you need...
Am I missing something? This function returns its own function name.
Prelude> let myNameIs::(a->b) -> String; myNameIs f = "myNameIs"
Prelude> :type myNameIs
myNameIs :: (a -> b) -> String
Prelude> myNameIs myNameIs
"myNameIs"
You can preprocess your source code with CPP. In CPP
#define _NAMEOF(name) #name
defines a macro, _NAMEOF, for stringifying text (including surrounding it with programmer's quotation marks). You can then use it as follows:
head [] = error $ _NAMEOF(head) ++ ": empty list!"
which CPP should translate into a valid Haskell source code line:
head [] = error $ "head" ++ ": empty list!"

Resources