Demonstrating that an expression has a type - programming-languages

I am working on a practice sheet for a final tomorow and I am a bit confused trying to figure out what the question is asking and how to resolve it. I wanted to check here and see if the good people of stack overflow can help me resolve it.
The question is set up like this:
Show a derivation tree (which is a trace of typecheck) demonstrating that the following expression has a type :
(appC (lamC ‘x ??? (plusC (idC ‘x) (numC 1)))
(numC 2) )
It is based on this definition of type check:
(define (typecheck [a : ExprC] [tenv : TypeEnv])
(type-case ExprC a
[numC (n) (numT)]
[plusC (l r) (typecheck-nums l r tenv)]
[multC (l r) (typecheck-nums l r tenv)]
[idC (n) (type-lookup n tenv)]
[lamC (n arg-type body)
(arrowT arg-type
(typecheck body
(extend-env (tbind n arg-type)
tenv)))]
[appC (fun arg)
(type-case Type (typecheck fun tenv)
[arrowT (arg-type result-type)
(if (equal? arg-type
(typecheck arg tenv))
result-type
(type-error arg
(to-string arg-type)))]
[else (type-error fun "function")])]))
(define (typecheck-nums l r tenv)
(type-case Type (typecheck l tenv)
[numT ()
(type-case Type (typecheck r tenv)
[numT () (numT)]
[else (type-error r "num")])]
[else (type-error l "num")]))
(define (type-error a msg)
(error 'typecheck (string-append
"no type: "
(string-append
(to-string a)
(string-append " not "
msg)))))
When I run this in racket :
(typecheck (appC
(lamC 'x (numT) (plusC (idC 'x) (numC 1)))
(numC 2))
mt-env)
I do get:
- Type
(numT)
- Type
(numT)
At the bottom it states :
"You check that the type for 'x must be : numT"
So it is coming up with numT but I am confused about the tracing part, I know this question is long but this is the one out of all of the practice questions that is confusing me the most. Any advice/help is appreciated

The question: "Show a derivation tree demonstrating that the following expression has a type" means that you need to make a proof that the expression has the given type.
Consider this example (unrelated to your typecheck example):
The result of evaluating the expression (+ 1 2) has type int.
Why:
The subexpression 1 has type int
The subexpression 2 has type int
The subexpression + has type int int -> int
Due to the type above the rule for application states that
applying a function of type int int -> int to two arguments of type int, has a result of type int.
A type checker examines an expression recursively. It determines the types of the subexpressions first, and then use their types to infer the types of compound expressions.
In order to get a proof that a given expression has a certain type, one can use the trace of running the type checker. To get the trace, modify typechecker to print the types as they are inferred.
Untested modification:
(define (typecheck [a : ExprC] [tenv : TypeEnv])
(define (tell result-type)
(display "The type of ")
(display a)
(display " is: ")
(display result-type)
(newline))
(tell
(type-case ExprC a
[numC (n) (numT)]
[plusC (l r) (typecheck-nums l r tenv)]
[multC (l r) (typecheck-nums l r tenv)]
[idC (n) (type-lookup n tenv)]
[lamC (n arg-type body) (arrowT arg-type
(typecheck body
(extend-env (tbind n arg-type)
tenv)))]
[appC (fun arg) (type-case Type (typecheck fun tenv)
[arrowT (arg-type result-type)
(if (equal? arg-type
(typecheck arg tenv))
result-type
(type-error arg
(to-string arg-type)))]
[else (type-error fun "function")])])))

Related

Lambda abstraction pattern matching in haskell

I am trying to write a function which outputs all variable names. When used on the example below, the output should be
*Main> used example
["a","b","x","y"]
This is what I have written so far...
import Data.Char
import Data.List
type Var = String
data Term =
Variable Var
| Lambda Var Term
| Apply Term Term
-- deriving Show
instance Show Term where
show = pretty
example :: Term
example = Lambda "a" (Lambda "x" (Apply (Apply (Lambda "y" (Variable "a")) (Variable "x")) (Variable "b")))
pretty :: Term -> String
pretty = f 0
where
f i (Variable x) = x
f i (Lambda x m) = if i /= 0 then "(" ++ s ++ ")" else s where s = "\\" ++ x ++ ". " ++ f 0 m
f i (Apply n m) = if i == 2 then "(" ++ s ++ ")" else s where s = f 1 n ++ " " ++ f 2 m
used :: Term -> [Var]
used (Variable n) = [n]
used (Lambda n t) = "\\" ++ n ++ ". " ++ used t
used (Apply t1 t2) = used t1 ++ used t2
The problem lies in the line used (Lambda n t) = "\\" ++ n ++ ". " ++ used t, I get this error message:
list.hs:28:47: error:
lexical error in string/character literal at character '\n'
|
28 | used (Lambda n t) = "\" ++ n ++ ". " ++ used t
Why am I getting this complaint?
You are copying and pasting from examples too much. Keep thinking about what the function is supposed to mean as you are writing it.
used (Variable n) = [n]
This is correct: the set of variables used in a term which is just a variable is the variable used. For example, the set of variables used in the term x is just [x].
used (Apply t1 t2) = used t1 ++ used t2
This is also correct1: the set of variables used in say (x y z) (w x y) is the union of the variables used in x y z and in w x y: that is [x,y,z,w,x,y].
So now let's consider the case you are struggling with.
used (Lambda n t) = ...
The code you have seems to be attempting to print the the term into a string, which is not what we are trying to do here -- we are trying to find the set of used variables.
Let's consider an example: we have a term like (\x. x y z), and we want to find out what its used variables are. Before trying to come up with the general solution, ask yourself what the result should be in this example.
If this function is going to be nicely recursive, can we express your expected result in terms of the used variables of x y z? How do we transform the set of used variables of x y z into the set of used variables of \x. x y z?
1 Though you might get duplicates.

Haskell Caesar Cypher, I dont get interpreter errors

it's my first post here :)
I'm trying to learn basics of haskell and something is even showing on my screen ( ͡° ͜ʖ ͡°)
But seriously. I'm trying to implement Caesar's Cipher, but I dont have a clue why my dance with ord and chr is not working. I realize that the answers is pretty simple but I find it difficult to understand GHCI's error messages.
import Data.Char
cipher :: [char] -> Int -> [char]
cipher [] _ = []
cipher ch n = (chr(( (ord (head ch)) - n) `mod` 26)) : (cipher (tail ch) n)
cipher.hs:4:16:
Couldn't match expected type `char' with actual type `Char'
`char' is a rigid type variable bound by
the type signature for cipher :: [char] -> Int -> [char]
at cipher.hs:2:11
In the return type of a call of `chr'
In the first argument of `(:)', namely
`(chr (((ord (head ch)) - n) `mod` 26))'
In the expression:
(chr (((ord (head ch)) - n) `mod` 26)) : (cipher (tail ch) n)
As Jeff Burka says, you need Char not char to get the code to compile.
You can also simplify some of the parentheses - using HLint (which is built into IDEs like EclipseFP) is very helpful here:
cipher :: String -> Int -> String
cipher [] _ = []
cipher ch n = chr ((ord (head ch) - n) `mod` 26) : cipher (tail ch) n
You can simplify a bit by pattern matching the non-empty input list 'ch', so that you don't need to explicitly call head and tail:
cipher (h:t) n = chr ((ord h - n) `mod` 26) : cipher t n
Or just use map rather than explicitly recursing, as shown below.
After that, the main problem is that character values don't start from zero, so you need to subtract an offset before applying mod 26, then add the offset back again. Something like:
cipher2 [] _ = []
cipher2 c n = map shift c
where
a = ord 'A'
shift ch = chr (((ord ch - a + n) `mod` 26) + a)
(assuming we only care about characters A-Z).
> cipher2 "ABCDE" 1
"BCDEF"
> cipher2 "ABCDE" 26
"ABCDE"

Haskell: Why I can load this file in ghci but when I try to do the same in hugs I get a syntax error?

This is the file I am trying to load:
import Data.List (foldl')
import Text.Printf (printf)
import Data.Char (ord)
--data IntParsedStr = Int | ParsingError
--data ParsingError = ParsingError String
asInt :: String -> Either String Integer
asInt "" = Left "Empty string"
asInt xs#(x:xt) | x == '-' = either Left (Right . ((-1) *)) (asInt' xt)
| otherwise = either Left Right (asInt' xs)
where asInt' :: String -> Either String Integer
asInt' "" = Left "No digits"
asInt' xs = foldl' step (Right 0) xs
where step :: Either String Integer -> Char -> Either String Integer
step (Left e) _ = Left e
step (Right ac) c = either Left (Right . (10 * ac + ) . fromIntegral) (charAsInt c)
charAsInt :: Char -> Either String Int
charAsInt c | between (ord '0') (ord c) (ord '9') = Right $ ord c - ord '0'
| otherwise = Left $ printf "'%c' is not a digit" c
checkPrecision str = either error ((str == ). show) (asInt str)
between :: Ord t => t -> t -> t -> Bool
between a b c = a <= b && b <= c
It loads without any problem in ghci but in hugs I get this error:
ERROR "folds.hs":17 - Syntax error in expression (unexpected `)')
Line 17 is the last in the definition of asInt function
Edit:
Hi!
I recently founded that this is in fact a known hugs issue as said in this question
where there is a link to the Hugs 98 Users Guide where says that
Legal expressions like (a+b+) and (a*b+) are rejected.
I believe this is a bug in Hugs, not a liberality of GHC. The Haskell 98 report (appropriate in the context of Hugs usage) says
Syntactic precedence rules apply to sections as follows. (op e) is legal if and only if (x op e) parses in the same way as (x op (e)); and similarly for (e op). For example, (*a+b) is syntactically invalid, but (+a*b) and (*(a+b)) are valid. Because (+) is left associative, (a+b+) is syntactically correct, but (+a+b) is not; the latter may legally be written as (+(a+b)).
I interpret that as allowing (10 * ac + ) since both (*) and (+) are left associative, and indeed (*) has higher precedence.
As pointed out in the comments, ((10 * ac) + ) is accepted by both, so is a workaround.
Interestingly, this isn't listed in the Hugs vs Haskell 98 page, so maybe Mark P. Jones reads this section of the report differently to me. Certainly I can forgive him for this; Gofer implemented constructor classes long before Haskell allowed them, and Hugs is still faster than GHCi at compilation, and still gives better error messages.

Implementing a language interpreter in Haskell

I want to implement an imperative language interpreter in Haskell (for educational purposes). But it's difficult for me to create right architecture for my interpreter: How should I store variables? How can I implement nested function calls? How should I implement variable scoping? How can I add debugging possibilities in my language? Should I use monads/monad transformers/other techniques? etc.
Does anybody know good articles/papers/tutorials/sources on this subject?
If you are new to writing this kind of processors, I would recommend to put off using monads for a while and first focus on getting a barebones implementation without any bells or whistles.
The following may serve as a minitutorial.
I assume that you have already tackled the issue of parsing the source text of the programs you want to write an interpreter for and that you have some types for capturing the abstract syntax of your language. The language that I use here is very simple and only consists of integer expressions and some basic statements.
Preliminaries
Let us first import some modules that we will use in just a bit.
import Data.Function
import Data.List
The essence of an imperative language is that it has some form of mutable variables. Here, variables simply represented by strings:
type Var = String
Expressions
Next, we define expressions. Expressions are constructed from integer constants, variable references, and arithmetic operations.
infixl 6 :+:, :-:
infixl 7 :*:, :/:
data Exp
= C Int -- constant
| V Var -- variable
| Exp :+: Exp -- addition
| Exp :-: Exp -- subtraction
| Exp :*: Exp -- multiplication
| Exp :/: Exp -- division
For example, the expression that adds the constant 2 to the variable x is represented by V "x" :+: C 2.
Statements
The statement language is rather minimal. We have three forms of statements: variable assignments, while loops, and sequences.
infix 1 :=
data Stmt
= Var := Exp -- assignment
| While Exp Stmt -- loop
| Seq [Stmt] -- sequence
For example, a sequence of statements for "swapping" the values of the variables x and y can be represented by Seq ["tmp" := V "x", "x" := V "y", "y" := V "tmp"].
Programs
A program is just a statement.
type Prog = Stmt
Stores
Now, let us move to the actual interpreter. While running a program, we need to keep track of the values assigned to the different variables in the programs. These values are just integers and as a representation of our "memory" we just use lists of pairs consisting of a variable and a value.
type Val = Int
type Store = [(Var, Val)]
Evaluating expressions
Expressions are evaluated by mapping constants to their value, looking up the values of variables in the store, and mapping arithmetic operations to their Haskell counterparts.
eval :: Exp -> Store -> Val
eval (C n) r = n
eval (V x) r = case lookup x r of
Nothing -> error ("unbound variable `" ++ x ++ "'")
Just v -> v
eval (e1 :+: e2) r = eval e1 r + eval e2 r
eval (e1 :-: e2) r = eval e1 r - eval e2 r
eval (e1 :*: e2) r = eval e1 r * eval e2 r
eval (e1 :/: e2) r = eval e1 r `div` eval e2 r
Note that if the store contains multiple bindings for a variable, lookup selects the bindings that comes first in the store.
Executing statements
While the evaluation of an expression cannot alter the contents of the store, executing a statement may in fact result in an update of the store. Hence, the function for executing a statement takes a store as an argument and produces a possibly updated store.
exec :: Stmt -> Store -> Store
exec (x := e) r = (x, eval e r) : r
exec (While e s) r | eval e r /= 0 = exec (Seq [s, While e s]) r
| otherwise = r
exec (Seq []) r = r
exec (Seq (s : ss)) r = exec (Seq ss) (exec s r)
Note that, in the case of assignments, we simply push a new binding for the updated variable to the store, effectively shadowing any previous bindings for that variable.
Top-level Interpreter
Running a program reduces to executing its top-level statement in the context of an initial store.
run :: Prog -> Store -> Store
run p r = nubBy ((==) `on` fst) (exec p r)
After executing the statement we clean up any shadowed bindings, so that we can easily read off the contents of the final store.
Example
As an example, consider the following program that computes the Fibonacci number of the number stored in the variable n and stores its result in the variable x.
fib :: Prog
fib = Seq
[ "x" := C 0
, "y" := C 1
, While (V "n") $ Seq
[ "z" := V "x" :+: V "y"
, "x" := V "y"
, "y" := V "z"
, "n" := V "n" :-: C 1
]
]
For instance, in an interactive environment, we can now use our interpreter to compute the 25th Fibonacci number:
> lookup "x" $ run fib [("n", 25)]
Just 75025
Monadic Interpretation
Of course, here, we are dealing with a very simple and tiny imperative language. As your language gets more complex, so will the implementation of your interpreter. Think for example about what additions you need when you add procedures and need to distinguish between local (stack-based) storage and global (heap-based) storage. Returning to that part of your question, you may then indeed consider the introduction of monads to streamline the implementation of your interpreter a bit.
In the example interpreter above, there are two "effects" that are candidates for being captured by a monadic structure:
The passing around and updating of the store.
Aborting running the program when a run-time error is encountered. (In the implementation above, the interpreter simply crashes when such an error occurs.)
The first effect is typically captured by a state monad, the second by an error monad. Let us briefly investigate how to do this for our interpreter.
We prepare by importing just one more module from the standard libraries.
import Control.Monad
We can use monad transformers to construct a composite monad for our two effects by combining a basic state monad and a basic error monad. Here, however, we simply construct the composite monad in one go.
newtype Interp a = Interp { runInterp :: Store -> Either String (a, Store) }
instance Monad Interp where
return x = Interp $ \r -> Right (x, r)
i >>= k = Interp $ \r -> case runInterp i r of
Left msg -> Left msg
Right (x, r') -> runInterp (k x) r'
fail msg = Interp $ \_ -> Left msg
Edit 2018: The Applicative Monad Proposal
Since the Applicative Monad Proposal (AMP) every Monad must also be an instance of Functor and Applicative. To do this we can add
import Control.Applicative -- Otherwise you can't do the Applicative instance.
to the imports and make Interp an instance of Functor and Applicative like this
instance Functor Interp where
fmap = liftM -- imported from Control.Monad
instance Applicative Interp where
pure = return
(<*>) = ap -- imported from Control.Monad
Edit 2018 end
For reading from and writing to the store, we introduce effectful functions rd and wr:
rd :: Var -> Interp Val
rd x = Interp $ \r -> case lookup x r of
Nothing -> Left ("unbound variable `" ++ x ++ "'")
Just v -> Right (v, r)
wr :: Var -> Val -> Interp ()
wr x v = Interp $ \r -> Right ((), (x, v) : r)
Note that rd produces a Left-wrapped error message if a variable lookup fails.
The monadic version of the expression evaluator now reads
eval :: Exp -> Interp Val
eval (C n) = do return n
eval (V x) = do rd x
eval (e1 :+: e2) = do v1 <- eval e1
v2 <- eval e2
return (v1 + v2)
eval (e1 :-: e2) = do v1 <- eval e1
v2 <- eval e2
return (v1 - v2)
eval (e1 :*: e2) = do v1 <- eval e1
v2 <- eval e2
return (v1 * v2)
eval (e1 :/: e2) = do v1 <- eval e1
v2 <- eval e2
if v2 == 0
then fail "division by zero"
else return (v1 `div` v2)
In the case for :/:, division by zero results in an error message being produced through the Monad-method fail, which, for Interp, reduces to wrapping the message in a Left-value.
For the execution of statements we have
exec :: Stmt -> Interp ()
exec (x := e) = do v <- eval e
wr x v
exec (While e s) = do v <- eval e
when (v /= 0) (exec (Seq [s, While e s]))
exec (Seq []) = do return ()
exec (Seq (s : ss)) = do exec s
exec (Seq ss)
The type of exec conveys that statements do not result in values but are executed only for their effects on the store or the run-time errors they may trigger.
Finally, in the function run we perform a monadic computation and process its effects.
run :: Prog -> Store -> Either String Store
run p r = case runInterp (exec p) r of
Left msg -> Left msg
Right (_, r') -> Right (nubBy ((==) `on` fst) r')
In the interactive environment, we can now revisit the interpretation of our example program:
> lookup "x" `fmap` run fib [("n", 25)]
Right (Just 75025)
> lookup "x" `fmap` run fib []
Left "unbound variable `n'"
A couple of good papers I've finally found:
Building Interpreters by Composing Monads
Monad Transformers Step by Step - how incrementally build tiny interpreter using
monad transformers
How to build a monadic interpreter in one day
Monad Transformers and Modular Interpreters

Strange pattern matching with functions instancing Show

So I'm writing a program which returns a procedure for some given arithmetic problem, so I wanted to instance a couple of functions to Show so that I can print the same expression I evaluate when I test. The trouble is that the given code matches (-) to the first line when it should fall to the second.
{-# OPTIONS_GHC -XFlexibleInstances #-}
instance Show (t -> t-> t) where
show (+) = "plus"
show (-) = "minus"
main = print [(+),(-)]
returns
[plus,plus]
Am I just committing a mortal sin printing functions in the first place or is there some way I can get it to match properly?
edit:I realise I am getting the following warning:
Warning: Pattern match(es) are overlapped
In the definition of `show': show - = ...
I still don't know why it overlaps, or how to stop it.
As sepp2k and MtnViewMark said, you can't pattern match on the value of identifiers, only on constructors and, in some cases, implicit equality checks. So, your instance is binding any argument to the identifier, in the process shadowing the external definition of (+). Unfortunately, this means that what you're trying to do won't and can't ever work.
A typical solution to what you want to accomplish is to define an "arithmetic expression" algebraic data type, with an appropriate show instance. Note that you can make your expression type itself an instance of Num, with numeric literals wrapped in a "Literal" constructor, and operations like (+) returning their arguments combined with a constructor for the operation. Here's a quick, incomplete example:
data Expression a = Literal a
| Sum (Expression a) (Expression a)
| Product (Expression a) (Expression a)
deriving (Eq, Ord, Show)
instance (Num a) => Num (Expression a) where
x + y = Sum x y
x * y = Product x y
fromInteger x = Literal (fromInteger x)
evaluate (Literal x) = x
evaluate (Sum x y) = evaluate x + evaluate y
evaluate (Product x y) = evaluate x * evaluate y
integer :: Integer
integer = (1 + 2) * 3 + 4
expr :: Expression Integer
expr = (1 + 2) * 3 + 4
Trying it out in GHCi:
> integer
13
> evaluate expr
13
> expr
Sum (Product (Sum (Literal 1) (Literal 2)) (Literal 3)) (Literal 4)
Here's a way to think about this. Consider:
answer = 42
magic = 3
specialName :: Int -> String
specialName answer = "the answer to the ultimate question"
specialName magic = "the magic number"
specialName x = "just plain ol' " ++ show x
Can you see why this won't work? answer in the pattern match is a variable, distinct from answer at the outer scope. So instead, you'd have to write this like:
answer = 42
magic = 3
specialName :: Int -> String
specialName x | x == answer = "the answer to the ultimate question"
specialName x | x == magic = "the magic number"
specialName x = "just plain ol' " ++ show x
In fact, this is just what is going on when you write constants in a pattern. That is:
digitName :: Bool -> String
digitName 0 = "zero"
digitName 1 = "one"
digitName _ = "math is hard"
gets converted by the compiler to something equivalent to:
digitName :: Bool -> String
digitName x | x == 0 = "zero"
digitName x | x == 1 = "one"
digitName _ = "math is hard"
Since you want to match against the function bound to (+) rather than just bind anything to the symbol (+), you'd need to write your code as:
instance Show (t -> t-> t) where
show f | f == (+) = "plus"
show f | f == (-) = "minus"
But, this would require that functions were comparable for equality. And that is an undecidable problem in general.
You might counter that you are just asking the run-time system to compare function pointers, but at the language level, the Haskell programmer doesn't have access to pointers. In other words, you can't manipulate references to values in Haskell(*), only values themselves. This is the purity of Haskell, and gains referential transparency.
(*) MVars and other such objects in the IO monad are another matter, but their existence doesn't invalidate the point.
It overlaps because it treats (+) simply as a variable, meaning on the RHS the identifier + will be bound to the function you called show on.
There is no way to pattern match on functions the way you want.
Solved it myself with a mega hack.
instance (Num t) => Show (t -> t-> t) where
show op =
case (op 6 2) of
8 -> "plus"
4 -> "minus"
12 -> "times"
3 -> "divided"

Resources