I'm writing my own LISP based on Write Yourself a Scheme in 48 hours. (The code is here.) As a last exercise I want to implement macros. How can this be done considering that I represent expressions as a list of immutable datatypes. Can this be done simply in LISP itself or do I have to implement some function in Haskell?
My current implementation is written in Haskell and pretty much works like this:
Parse input and turn it into a list of expressions
Evaluates the expressions and substitute it tills it's a single expression
Return that expression and print it
The expressions is represented in Haskell like this:
data Expr
= Sym String
| List [Expr]
| Num Int
| Str String
| Bool Bool
| Func Env [String] Expr
| Prim ([Expr] -> ErrorOr Expr)
| Action ([Expr] -> IOErrorOr Expr)
Okey, now to the real problem. Macros doesn't evaluates its arguments but instead transforms into an expression by "placing" the arguments inside the form. Returning valid expression that may be evaluated or returned as a quoted list. I was thinking of implementing this by having a special evaluation function which only evaluates the symbols in the macros' form. How this could be achieved though is something I have problem understanding. The proper solution feels like I should "simply" modify the form by replacing the symbols inside it with the arguments, but that's not possible due to Haskell's immutability.
So, Clojure seems to have implemented macros in Lisp itself though. I can't interpret Clojure's solution but if this can be done it feels like being a bit easier than doing it in Haskell. I have no idea what macroexpand1(which macroexpand call) do, does it call some function from within Clojure's implementation? If so, then I still have to implement it inside Haskell.
If we look at how functions are evaluated:
eval env (List (op:args)) = do
func <- eval env op
args <- mapM (eval env) args
apply func args
apply :: Expr -> [Expr] -> IOErrorOr Expr
apply (Prim func) args = liftToIO $ func args
apply (Action func) args = func args
apply (Func env params form) args =
case length params == length args of
True -> (liftIO $ bind env $ zip params args)
>>= flip eval form
False -> throwError . NumArgs . toInteger $ length params
apply _ _ = error "apply"
So, if I wanna implement a macro system, then I could probably remove the evaluation part of the arguments, then bind the macros parameters to its arguments, and have a special eval which only evaluates every symbol in the form, returning a new form that has the arguments put inside it instead. This is what I can't implement though, and I'm not even sure the logic is correct.
I understand this question is quite wide and could probably be more simply asked with "How do I implement a macro system in my LISP implementation written in Haskell
You might try reading the interpreter implementations in Structure and Implementation of Computer Programs. The eval function that you show clearly only works for the default evaluation rule, and not for what the book calls special forms.
A normal Lisp eval function looks more like this:
eval env expr#(List _)
| isSpecialForm env expr = evalSpecial env expr
| otherwise = evalApplication env expr
evalApplication env (op:args) = do
func <- eval env op
args <- mapM (eval env) args
apply func args
evalSpecial env expr#(List (op:args))
| isMacro env op = eval env (macroExpand env expr)
| otherwise = case op of
"lambda" -> ...
"if" -> ...
-- etc.
No, macros can not be implemented in Lisp itself, that's the whole point to them. You have to macroexpand each macro call according to its definition, as part of loading/compiling/processing a given expression.
You would have to alter your eval implementation to call macros on unevaluated arguments, and feed the results back into eval (not apply, like processing the normal function application would). As suggested by sepp2k in the comments, you'd represent your macros as Func... expressions, but hold them in a separate environment, where only macros are stored.
see also: Lazy Evaluation vs Macros
You don't need a special version of apply. Just call the regular apply without evaluating the arguments and then eval the expression returned by apply.
Related
I remember seeing in Erlang, that a wrapper function of a recursive function will sometimes pass an atom that determines whether the recursion is at the first iteration (n = 1) or some successive iterations (n > 1). This is useful when a recursive function needs to change its behaviour after the first iteration. What is this pattern called?
Furthermore is this pattern also appropriate in Haskell? I wrote a small snippet using it, look at the first boolean:
import Data.Char (digitToInt, isDigit)
data Token = Num Integer deriving (Show)
tokeniseNumber :: String -> (String, Maybe Token)
tokeniseNumber input = accumulateNumber input 0 True
where
accumulateNumber :: String -> Integer -> Bool -> (String, Maybe Token)
accumulateNumber [] value True = ([], Nothing)
accumulateNumber [] value False = ([], Just (Num value))
accumulateNumber input#(peek:tail) value first =
case isDigit peek of
False | first -> (input, Nothing)
False | not first -> (input, Just (Num value))
True -> accumulateNumber tail (value * 10 + (toInteger . digitToInt) peek) False
-- Edit --
zxq9 posted an answer and later deleted. But I actually think the answer has merit.
This is cleaner to define as a set of separate functions that each behave some specific way, and a function head match that determines which of those functions to dispatch (Haskell provides a broader array of type-based function matching tools here). In other words, a certain style of "finite state machine" is what you are looking for.
The states can be styled as function names or as a state argument; which to use depends on the context and language, and this can extend to the state argument being a function name and that itself being a sort of match.
What is best for Haskell is usually not what works best for Erlang. Many one-off tasks are delegated to separate processes in Erlang, and even process instantiation in Erlang goes through an "init state" when it calls init, which is essentially the same thing as when you say "when a recursive function needs to change its behaviour after the first iteration". OTOH, Haskell provides more ways to match on a function head. In either case taking an approach where a named function defines an operating state is cleaner. The result will be code that is not nested, doesn't require procedural conditionals, and can be called from anywhere more easily (more flexibly dealt with when you re-write your program later...).
FSMs are a general way of determining what code to execute based on state, and initialization of a function (or process) is a special case of that. I've heard this called "pass-through initialization" as in, the entry function defines the interface, does one-time processing to set up the main procedure and passes execution through to it:
init(Args) ->
{ok, NewArgs} = one_time_processing(Args),
loop(NewArgs).
loop(Args) ->
{ok, NewArgs} = do_stuff(Args),
loop(NewArgs).
Of course, the above is an infinite loop, so its more common to either have a check for exit at the end of the loop/1 function, or (more often) a match in the function head of loop:
loop(done, Args) ->
Args;
loop(cont, Args) ->
{Cond, NewArgs} = do_stuff(Args),
loop(Cond, NewArgs).
But in either case it is better to have the initialization of a process be its own procedure, separately defined from whatever the body of the loop is. Other languages with looping constructs handle this differently with some combination of conditional checks applied a special way based on which style of loop the programmer chooses, but the effect is the same. Very often the most obvious way to implement this procedurally is to do the same: wrap the whole loop behind a function call, and the steps that precede the loop are the "one time" initialization parts. In this case its not that the loop is "wrapped" in a function call, but that you write an interface function to access it which does some one-time initialization on the way to calling it.
To expand on my comment about boolean blindness, I don't just mean using another type isomorphic to 2, but rather, using the right type to encode the reason your recursive function cares about which iteration it is.
Compare your code to the following version which is I'd say cleaner and more succint. It hinges on passing a Maybe Integer instead of an (Integer, Bool) to accumulateNumber.
import Data.Char (digitToInt, isDigit)
import Data.Maybe
import Control.Applicative
data Token = Num Integer deriving (Show)
tokeniseNumber :: String -> (String, Maybe Token)
tokeniseNumber input = accumulateNumber input Nothing
where
accumulateNumber :: String -> Maybe Integer -> (String, Maybe Token)
accumulateNumber input#(peek:tail) value
| isDigit peek = accumulateNumber tail (Just $ toNum (fromMaybe 0 value) peek)
accumulateNumber input value = (input, Num <$> value)
toNum value peek = value * 10 + (toInteger . digitToInt) peek
Also wanted to point out that I discovered an academic paper that discusses this exact technique.
It's called the "The worker/wrapper transformation" by Andy Gill & Graham Hutton (2009)
Link: http://www.cs.nott.ac.uk/~gmh/wrapper.pdf
I'm trying to better understand Haskell's laziness, such as when it evaluates an argument to a function.
From this source:
But when a call to const is evaluated (that’s the situation we are interested in, here, after all), its return value is evaluated too ... This is a good general principle: a function obviously is strict in its return value, because when a function application needs to be evaluated, it needs to evaluate, in the body of the function, what gets returned. Starting from there, you can know what must be evaluated by looking at what the return value depends on invariably. Your function will be strict in these arguments, and lazy in the others.
So a function in Haskell always evaluates its own return value? If I have:
foo :: Num a => [a] -> [a]
foo [] = []
foo (_:xs) = map (* 2) xs
head (foo [1..]) -- = 4
According to the above paragraph, map (* 2) xs, must be evaluated. Intuitively, I would think that means applying the map to the entire list- resulting in an infinite loop.
But, I can successfully take the head of the result. I know that : is lazy in Haskell, so does this mean that evaluating map (* 2) xs just means constructing something else that isn't fully evaluated yet?
What does it mean to evaluate a function applied to an infinite list? If the return value of a function is always evaluated when the function is evaluated, can a function ever actually return a thunk?
Edit:
bar x y = x
var = bar (product [1..]) 1
This code doesn't hang. When I create var, does it not evaluate its body? Or does it set bar to product [1..] and not evaluate that? If the latter, bar is not returning its body in WHNF, right, so did it really 'evaluate' x? How could bar be strict in x if it doesn't hang on computing product [1..]?
First of all, Haskell does not specify when evaluation happens so the question can only be given a definite answer for specific implementations.
The following is true for all non-parallel implementations that I know of, like ghc, hbc, nhc, hugs, etc (all G-machine based, btw).
BTW, something to remember is that when you hear "evaluate" for Haskell it normally means "evaluate to WHNF".
Unlike strict languages you have to distinguish between two "callers" of a function, the first is where the call occurs lexically, and the second is where the value is demanded. For a strict language these two always coincide, but not for a lazy language.
Let's take your example and complicate it a little:
foo [] = []
foo (_:xs) = map (* 2) xs
bar x = (foo [1..], x)
main = print (head (fst (bar 42)))
The foo function occurs in bar. Evaluating bar will return a pair, and the first component of the pair is a thunk corresponding to foo [1..]. So bar is what would be the caller in a strict language, but in the case of a lazy language it doesn't call foo at all, instead it just builds the closure.
Now, in the main function we actually need the value of head (fst (bar 42)) since we have to print it. So the head function will actually be called. The head function is defined by pattern matching, so it needs the value of the argument. So fst is called. It too is defined by pattern matching and needs its argument so bar is called, and bar will return a pair, and fst will evaluate and return its first component. And now finally foo is "called"; and by called I mean that the thunk is evaluated (entered as it's sometimes called in TIM terminology), because the value is needed. The only reason the actual code for foo is called is that we want a value. So foo had better return a value (i.e., a WHNF). The foo function will evaluate its argument and end up in the second branch. Here it will tail call into the code for map. The map function is defined by pattern match and it will evaluate its argument, which is a cons. So map will return the following {(*2) y} : {map (*2) ys}, where I have used {} to indicate a closure being built. So as you can see map just returns a cons cell with the head being a closure and the tail being a closure.
To understand the operational semantics of Haskell better I suggest you look at some paper describing how to translate Haskell to some abstract machine, like the G-machine.
I always found that the term "evaluate," which I had learned in other contexts (e.g., Scheme programming), always got me all confused when I tried to apply it to Haskell, and that I made a breakthrough when I started to think of Haskell in terms of forcing expressions instead of "evaluating" them. Some key differences:
"Evaluation," as I learned the term before, strongly connotes mapping expressions to values that are themselves not expressions. (One common technical term here is "denotations.")
In Haskell, the process of forcing is IMHO most easily understood as expression rewriting. You start with an expression, and you repeatedly rewrite it according to certain rules until you get an equivalent expression that satisfies a certain property.
In Haskell the "certain property" has the unfriendly name weak head normal form ("WHNF"), which really just means that the expression is either a nullary data constructor or an application of a data constructor.
Let's translate that to a very rough set of informal rules. To force an expression expr:
If expr is a nullary constructor or a constructor application, the result of forcing it is expr itself. (It's already in WHNF.)
If expr is a function application f arg, then the result of forcing it is obtained this way:
Find the definition of f.
Can you pattern match this definition against the expression arg? If not, then force arg and try again with the result of that.
Substitute the pattern match variables in the body of f with the parts of (the possibly rewritten) arg that correspond to them, and force the resulting expression.
One way of thinking of this is that when you force an expression, you're trying to rewrite it minimally to reduce it to an equivalent expression in WHNF.
Let's apply this to your example:
foo :: Num a => [a] -> [a]
foo [] = []
foo (_:xs) = map (* 2) xs
-- We want to force this expression:
head (foo [1..])
We will need definitions for head and `map:
head [] = undefined
head (x:_) = x
map _ [] = []
map f (x:xs) = f x : map f x
-- Not real code, but a rule we'll be using for forcing infinite ranges.
[n..] ==> n : [(n+1)..]
So now:
head (foo [1..]) ==> head (map (*2) [1..]) -- using the definition of foo
==> head (map (*2) (1 : [2..])) -- using the forcing rule for [n..]
==> head (1*2 : map (*2) [2..]) -- using the definition of map
==> 1*2 -- using the definition of head
==> 2 -- using the definition of *
I believe the idea must be that in a lazy language if you're evaluating a function application, it must be because you need the result of the application for something. So whatever reason caused the function application to be reduced in the first place is going to continue to need to reduce the returned result. If we didn't need the function's result we wouldn't be evaluating the call in the first place, the whole application would be left as a thunk.
A key point is that the standard "lazy evaluation" order is demand-driven. You only evaluate what you need. Evaluating more risks violating the language spec's definition of "non-strict semantics" and looping or failing for some programs that should be able to terminate; lazy evaluation has the interesting property that if any evaluation order can cause a particular program to terminate, so can lazy evaluation.1
But if we only evaluate what we need, what does "need" mean? Generally it means either
a pattern match needs to know what constructor a particular value is (e.g. I can't know what branch to take in your definition of foo without knowing whether the argument is [] or _:xs)
a primitive operation needs to know the entire value (e.g. the arithmetic circuits in the CPU can't add or compare thunks; I need to fully evaluate two Int values to call such operations)
the outer driver that executes the main IO action needs to know what the next thing to execute is
So say we've got this program:
foo :: Num a => [a] -> [a]
foo [] = []
foo (_:xs) = map (* 2) xs
main :: IO ()
main = print (head (foo [1..]))
To execute main, the IO driver has to evaluate the thunk print (head (foo [1..])) to work out that it's print applied to the thunk head (foo [1..]). print needs to evaluate its argument on order to print it, so now we need to evaluate that thunk.
head starts by pattern matching its argument, so now we need to evaluate foo [1..], but only to WHNF - just enough to tell whether the outermost list constructor is [] or :.
foo starts by pattern matching on its argument. So we need to evaluate [1..], also only to WHNF. That's basically 1 : [2..], which is enough to see which branch to take in foo.2
The : case of foo (with xs bound to the thunk [2..]) evaluates to the thunk map (*2) [2..].
So foo is evaluated, and didn't evaluate its body. However, we only did that because head was pattern matching to see if we had [] or x : _. We still don't know that, so we must immediately continue to evaluate the result of foo.
This is what the article means when it says functions are strict in their result. Given that a call to foo is evaluated at all, its result will also be evaluated (and so, anything needed to evaluate the result will also be evaluated).
But how far it needs to be evaluated depends on the calling context. head is only pattern matching on the result of foo, so it only needs a result to WHNF. We can get an infinite list to WHNF (we already did so, with 1 : [2..]), so we don't necessarily get in an infinite loop when evaluating a call to foo. But if head were some sort of primitive operation implemented outside of Haskell that needed to be passed a completely evaluated list, then we'd be evaluating foo [1..] completely, and thus would never finish in order to come back to head.
So, just to complete my example, we're evaluating map (2 *) [2..].
map pattern matches its second argument, so we need to evaluate [2..] as far as 2 : [3..]. That's enough for map to return the thunk (2 *) 2 : map (2 *) [3..], which is in WHNF. And so it's done, we can finally return to head.
head ((2 *) 2 : map (2 *) [3..]) doesn't need to inspect either side of the :, it just needs to know that there is one so it can return the left side. So it just returns the unevaluated thunk (2 *) 2.
Again though, we only evaluated the call to head this far because print needed to know what its result is, so although head doesn't evaluate its result, its result is always evaluated whenever the call to head is.
(2 *) 2 evaluates to 4, print converts that into the string "4" (via show), and the line gets printed to the output. That was the entire main IO action, so the program is done.
1 Implementations of Haskell, such as GHC, do not always use "standard lazy evaluation", and the language spec does not require it. If the compiler can prove that something will always be needed, or cannot loop/error, then it's safe to evaluate it even when lazy evaluation wouldn't (yet) do so. This can often be faster so GHC optimizations do actually do this.
2 I'm skipping over a few details here, like that print does have some non-primitive implementation we could step inside and lazily evaluate, and that [1..] could be further expanded to the functions that actually implement that syntax.
Not necessarily. Haskell is lazy, meaning that it only evaluates when it needs to. This has some interesting effects. If we take the below code, for example:
-- File: lazinessTest.hs
(>?) :: a -> b -> b
a >? b = b
main = (putStrLn "Something") >? (putStrLn "Something else")
This is the output of the program:
$ ./lazinessTest
Something else
This indicates that putStrLn "Something" is never evaluated. But it's still being passed to the function, in the form of a 'thunk'. These 'thunks' are unevaluated values that, rather than being concrete values, are like a breadcrumb-trail of how to compute the value. This is how Haskell laziness works.
In our case, two 'thunks' are passed to >?, but only one is passed out, meaning that only one is evaluated in the end. This also applies in const, where the second argument can be safely ignored, and therefore is never computed. As for map, GHC is smart enough to realise that we don't care about the end of the array, and only bothers to compute what it needs to, in your case the second element of the original list.
However, it's best to leave the thinking about laziness to the compiler and keep coding, unless you're dealing with IO, in which case you really, really should think about laziness, because you can easily go wrong, as I've just demonstrated.
There are lots and lots of online articles on the Haskell wiki to look at, if you want more detail.
Function could evaluate either return type:
head (x:_) = x
or exception/error:
head _ = error "Head: List is empty!"
or bottom (⊥)
a = a
b = last [1 ..]
In my program for solving discrete maths, I want to let the user input a string of logic operations; e.g., if the user inputs let f (x:y:_) = x && y, then I would get a function f for use in the rest of the program. In GHCi, I can easily test my program by inputting let f (x:y:_) = x && y.
I have no idea how to achieve this task. I have taken a look into the eval function from the plugins package, but it seems not to be the right function. Can I do this in Haskell?
The code I'm planning to use this with is:
type TruthTable = [[Bool]]
type TruthTableResult = [([Bool], Bool)]
solveTable :: ([Bool] -> Bool) -> Integer -> (TruthTableResult)
solveTable f n = let table = truthTable n
result = map f table
in zipWith (\v r -> (v, r)) table result
There is no standard Haskell function, because Haskell is complied, not interpreted. However, there are libraries that allow you to read and compile Haskell code at run time. One of them is hint. Example for your case:
import Control.Monad
import Language.Haskell.Interpreter
main = do
-- fExpr is a Haskell code supplied by your user as a String
let fExpr = "let f (x:y:_) = x && y in f"
-- Create an interpreter that runs fExpr
r <- runInterpreter $ do
setImports ["Prelude"]
interpret fExpr (const True :: [Bool] -> Bool)
-- run it and get an interface to the function
case r of
Left err -> putStrLn $ "Ups... " ++ (show err)
Right f -> do
print $ f [True, False]
print $ f [True, True]
More examples available here.
You are writing an eval function - a form of runtime metaprogramming.
eval :: String -> a
If the string represents a Haskell program, then you must parse the string, type check it, and then compile it to a target interpreter or runtime. This requires access to the compiler as a library, either exported as a runtime service (in an interpreter) or as a separate package (as for a compiler).
The GHC implementation of Haskell has several libraries for doing runtime evaluation of Haskell code:
via the GHCi interpreter- hint
via the compiler - plugins
These apply only if your input language is Haskell.
If instead your input string represents a program in some other language, then you are looking for a DSL interpreter. This can be done by writing your own interpreter for the input language (or reusing a library if it is a common language).
The short answer is that Haskell has no "eval" function, unlike interpreted languages which can do this quite easily (after all, they have the interpreter handy and already running).
You can include the Haskell compiler as a library: see http://www.haskell.org/haskellwiki/GHC/As_a_library. This is the nearest thing to what you ask for.
However it sounds like you don't want the whole of Haskell here; what you are really want is a different language which may have Haskell-like syntax but is not the whole of Haskell. If so then the real solution is to define that language and write a parser for it. The Parsec library is the place to start for that.
Hi I'm writing an interpreter of C-like, statically typed language in Haskell. I want to perform typechecking before an execution of code, but I have some problems with it. First of all, below there are some type definitions from my abstract syntax:
newtype Ident = Ident String deriving (Eq,Ord,Show)
data Exp = {-- some other value constructors --} | EFuncWithParams Ident [Exp]
data Type = TInt | TDouble | {-- some other value constructors --} | TFunction [Exp]
type TCM a = ErrorT String (Reader Env) a
TCM is for reporting errors and passing the enviroment, eg:
typeof (EVar v) = do
env <- ask
case M.lookup v env of
Nothing -> throwError $ "undefined variable" ++ v ++ "\n"
Just t - > return t
Now I want to check type of expressions so I have following function that performs checks:
typeof Exp :: Exp -> TCM Type
It is defined for all cases but one:
typeof (EFuncWithParams f l)
I'm stuck here. What I think I should do is to check the type of f (I mean first of all check if it really IS a function) and see whether types of arguments that are recorded in definition of f match types of arguments that are actually passed. Unfortunately I'm a haskell newbie and have no idea on how to express it the right way. Any suggestions will be highly appreciated :)
EDIT:
OK, It may not be implied by what I wrote here previously but EFuncWithParams Ident [Exp] is a function call actually (Yes, I know it is somewhat misleading) and I want to be able to call a function like f(2 + 3, a, b[0]) and this is why I used TFunction [Exp]. Function declaration and definition is a statement and is defined:
data Function_def =
Func Type_specifier Declarator Compound_stm
deriving (Eq,Ord,Show)
where Declarator is:
data Declarator = FuncDec Ident Parameter_declarations
Parameter declarations is a list of Type_specifiers and Idents
What I think I should do is to save function type in a map while checking its declaration, and then fetch it here. I mean I also have:
typeof_stm :: Stm -> TCM Type -- Function_def is a statement
The problem is that I have a separate function for type-checking statements and I am in doubt whether the map that is used by one function (eg. typeof_stm) is passed automatically to another one (eg. typeof). I see no way of this to happen but maybe I'm wrong.
I think your function type is wrong. You have it as TFunction [Exp], it should be TFunction [Type] Type (a list of argument types and a return type).
Typechecking code for a function call would look something like
case ... of ...
EFuncWithParams ident args -> do
t <- typeof (EVar ident)
ts <- mapM typeof args
case t of
TFunction ps r -> if ts == ps
then return r
else throwError $ "parameter types do not match"
_ -> throwError $ "called id " ++ ident ++ " which is not a function"
This pseudo-code probably goes in and out of the monad improperly, please bear with me, I don't have all of your code so I cannot really typecheck what I have done. But the overall scheme is like this. You probably will want to give more detailed error report if parameter types do not match (which ones don't match, or perhaps there's a wrong number of parameters).
I'm not practical with Haskell, I just did it in OCaml and in C++ but what you are going to do is to call the type checker function recursively on each parameter and check if they do correspond.
What I mean is that you'll have to type check something that is like
FunCall ident, exp list
Now you'll have in the environment an entry for the function with the types of parameters associated so what you need to ensure in order is that:
function named ident does exist in the environment
the number of parameters is equal to the definition (this can be done implicitly by the param checking function, see below)
for every parameter you call typeof (exp1) and you check that the returned TCM Type is the same of the corresponding parameter
This is how it should work. In OCaml (which is somewhat similar to Haskell) I would do something like:
match exp with
| FunCall ident, (param list) ->
(* get fundecl from ident *)
(* call check_params list_of_parameters, list_of_type_of_parameters *)
(* if check params return true then type check value of the function is the return value *)
let check_params list decl_list =
match list, decl_list with
| [], [] -> true
| p :: rp, d :: rd -> typeof(p) = d && check_params rp rd
| _ -> false
EFuncWithParams Ident [Exp]
It is typical for languages like yours to require a type annotation on the input, and possibly also a type annotation on the output. So if you add this info to that constructor
EFuncWithparams { inType, outType :: Type
, funcInput :: Ident
, funcBody :: [Expr] }
Now to typecheck it, you simply:
Add the binding of funcInput to inType to your type environment
Ascertain the type of funcBody with the new type environment
Make sure it matches with outType.
You should also check function applications to make sure that the input matches the function's inType, and that the results are used correctly according to its outType.
A few basic questions, for converting SML code to Haskell.
1) I am used to having local embedded expressions in SML code, for example test expressions, prints, etc. which functions local tests and output when the code is loaded (evaluated).
In Haskell it seems that the only way to get results (evaluation) is to add code in a module, and then go to main in another module and add something to invoke and print results.
Is this right? in GHCi I can type expressions and see the results, but can this be automated?
Having to go to the top level main for each test evaluation seems inconvenient to me - maybe just need to shift my paradigm for laziness.
2) in SML I can do pattern matching and unification on a returned result, e.g.
val myTag(x) = somefunct(a,b,c);
and get the value of x after a match.
Can I do something similar in Haskell easily, without writing separate extraction functions?
3) How do I do a constructor with a tuple argument, i.e. uncurried.
in SML:
datatype Thing = Info of Int * Int;
but in Haskell, I tried;
data Thing = Info ( Int Int)
which fails. ("Int is applied to too many arguments in the type:A few Int Int")
The curried version works fine,
data Thing = Info Int Int
but I wanted un-curried.
Thanks.
This question is a bit unclear -- you're asking how to evaluate functions in Haskell?
If it is about inserting debug and tracing into pure code, this is typically only needed for debugging. To do this in Haskell, you can use Debug.Trace.trace, in the base package.
If you're concerned about calling functions, Haskell programs evaluate from main downwards, in dependency order. In GHCi you can, however, import modules and call any top-level function you wish.
You can return the original argument to a function, if you wish, by making it part of the function's result, e.g. with a tuple:
f x = (x, y)
where y = g a b c
Or do you mean to return either one value or another? Then using a tagged union (sum-type), such as Either:
f x = if x > 0 then Left x
else Right (g a b c)
How do I do a constructor with a tuple argument, i.e. uncurried in SML
Using the (,) constructor. E.g.
data T = T (Int, Int)
though more Haskell-like would be:
data T = T Int Bool
and those should probably be strict fields in practice:
data T = T !Int !Bool
Debug.Trace allows you to print debug messages inline. However, since these functions use unsafePerformIO, they might behave in unexpected ways compared to a call-by-value language like SML.
I think the # syntax is what you're looking for here:
data MyTag = MyTag Int Bool String
someFunct :: MyTag -> (MyTag, Int, Bool, String)
someFunct x#(MyTag a b c) = (x, a, b, c) -- x is bound to the entire argument
In Haskell, tuple types are separated by commas, e.g., (t1, t2), so what you want is:
data Thing = Info (Int, Int)
Reading the other answers, I think I can provide a few more example and one recommendation.
data ThreeConstructors = MyTag Int | YourTag (String,Double) | HerTag [Bool]
someFunct :: Char -> Char -> Char -> ThreeConstructors
MyTag x = someFunct 'a' 'b' 'c'
This is like the "let MyTag x = someFunct a b c" examples, but it is a the top level of the module.
As you have noticed, Haskell's top level can defined commands but there is no way to automatically run any code merely because your module has been imported by another module. This is entirely different from Scheme or SML. In Scheme the file is interpreted as being executed form-by-form, but Haskell's top level is only declarations. Thus Libraries cannot do normal things like run initialization code when loaded, they have to provide a "pleaseRunMe :: IO ()" kind of command to do any initialization.
As you point out this means running all the tests requires some boilerplate code to list them all. You can look under hackage's Testing group for libraries to help, such as test-framework-th.
For #2, yes, Haskell's pattern matching does the same thing. Both let and where do pattern matching. You can do
let MyTag x = someFunct a b c
in ...
or
...
where MyTag x = someFunct a b c