type Expr = Const Float | Var String| Add Expr Expr| Mult Expr Expr
list = [3,1,4]
polyX : List Float -> Expr
polyX coeffs = polyHelper <| map Const <| coeffs
polyHelper: List Expr -> Expr
polyHelper e = case e of
[x] -> x
(x::xs) -> Add x(Mult(Var "x")(polyHelper xs))
[] -> Const 1
type Instr = LoadImmediate RegisterNumber --put value here
RegisterValue --the value
| Addition RegisterNumber --put result here
RegisterNumber --first thing to add
RegisterNumber --first thing to multiply
| Multiply RegisterNumber --put result here
RegisterNumber --first thing to multiply
RegisterNumber --second thing to multiply
type RegisterNumber = Int
type RegisterValue = Float
expr2Code : Expr -> List Instr
expr2Code expr = e2C 1 expr
e2C result expr = case expr of
Const x -> ((LoadImmediate(result+2))x)
Add expr1 expr2 -> (Addition result result (result+1))::(e2C result expr2)++(e2C result expr1)
Mult expr1 expr2 -> (Mult result result(result+1))::(e2C result expr2)++(e2C result expr1)
Var x -> []
I am having difficulty with an assignment.
Question:
Assume that the only variable you will see is x and it is already in register 2. Arrange for the result to arrive to be in register 1 at the end of the computation, and use registers 3 and 4 for other values, as needed. Write the helper function e2C to complete.
My T.A says that the code I have right now will compile, but it will not solve for the question.
Can anyone tell me how to fix the code so it will solve for the question?
Getting it to compile
Well, you're TA is wrong, that code snippet does not compile. Here's a compiling version:
type Expr
= Const Float
| Var String
| Add Expr Expr
| Mult Expr Expr
type Instr
= LoadImmediate RegisterNumber --put value here
RegisterValue --the value
| Addition RegisterNumber --put result here
RegisterNumber --first thing to add
RegisterNumber --first thing to multiply
| Multiply RegisterNumber --put result here
RegisterNumber --first thing to multiply
RegisterNumber --second thing to multiply
type alias RegisterNumber
= Int
type alias RegisterValue
= Float
list : List Float
list =
[3,1,4]
polyX : List Float -> Expr
polyX coeffs =
polyHelper <| List.map Const <| coeffs
polyHelper: List Expr -> Expr
polyHelper e =
case e of
[x] ->
x
(x::xs) ->
Add x (Mult (Var "x") (polyHelper xs))
[] ->
Const 1
expr2Code : Expr -> List Instr
expr2Code expr =
e2C 1 expr
e2C : RegisterNumber -> Expr -> List Instr
e2C result expr =
case expr of
Const x ->
[LoadImmediate (result+2) x]
Add expr1 expr2 ->
Addition result result (result+1)
:: e2C result expr2 ++ e2C result expr1
Mult expr1 expr2 ->
Multiply result result (result+1)
:: e2C result expr2 ++ e2C result expr1
Var x ->
[]
I've formatted the code more in accordance with the style guide. I found the following problems before your code compiled:
polyX used an unqualified map function, but there are no imports, so you should use the qualified List.map.
The types RegisterNumber and RegisterValue are type aliases. Use type alias for those, otherwise you're defining constructors Int and Float for completely independent types RegisterNumber and RegisterValue instead of relating those to the types Int andFloat`.
The Const branch in e2C wasn't returning a list, but the other branches of the case were.
The Mult branch in e2C was using Mult instead of Multiply for the result, which is an Expr, not an Instr.
Getting it to work
DISCLAIMER: Check you school/course regulations on FRAUD. In my experience, students are expected to submit only solutions that they wrote themselves. High-level discussions about solutions are usually OK, copying code is most likely NOT OK. This answer may go into too much detail according to your school's fraud regulations. Citing your sources is not always enough!
Given the three instructions that you can do, it's not easy to move a result from one register into another. That'll require bogus instructions like [LoadImmediate freeRegister 0, Addition moveToThisRegister MoveFromThisRegister freeRegister]. So you can't elegantly create an elaborate compiler, and you probably don't have to, given that you're only asked to complete helper function e2C.
So we're going for the easy, non-general solution. You'll want to make some assumptions about the Expr that you get in. Note that polyX only generates additions and multiplications that have a somehow constant (Const or Var) left-hand side. This is the property we'll exploit.
So if you do the right-hand side expressions first, and give that expression the same result register that you're given, then you still have both free registers (3 and 4) for your left-hand side. Use only one of them consistently, then do the operation between the result register and the chosen free register.
Moving the value of variable x to a different register is kind of ugly when there is no move operation. But it's fairly general, so let's use the left-over free register to add 0 to the value of variable x and save that value to the register that we're supposed to put the result in. This gives you the following implementation:
registerOfX : RegisterNumber
registerOfX = 2
freeRegister1 : RegisterNumber
freeRegister1 = 3
freeRegister2 : RegisterNumber
freeRegister2 = 4
e2C : RegisterNumber -> Expr -> List Instr
e2C resultRegister expr =
case expr of
Const value ->
[LoadImmediate resultRegister value]
Add expr1 expr2 ->
e2C resultRegister expr2
++ e2C freeRegister1 expr1
++ [Addition resultRegister freeRegister1 resultRegister]
Mult expr1 expr2 ->
e2C resultRegister expr2
++ e2C freeRegister1 expr1
++ [Multiply resultRegister freeRegister1 resultRegister]
Var "x" ->
[LoadImmediate freeRegister2 0, Addition resultRegister registerOfX freeRegister2]
Var _ ->
"Cannot handle "
++ toString expr
++ ", we only know of "
++ toString (Var "x")
|> Debug.crash
One final note, since this is already a long answer. You'll see that this code results in some redundant LoadImmediate 4 0 instructions. You can add a signal instruction for it to the front of the list by doing something like LoadImmediate freeRegister2 0 :: case expr of .... Then you can move variable x to a register in one instruction. Any further minimisation of the instructions will require extra steps that are best done in further helper functions, or you'll need to make the code less general by directly matching on Mult (Var "x") expr2 and use the register of variable x directly.
Related
I have this code which I'd like to condense
runFn someFn $ toArray a1 $ toArray a2 $ toArray a3 $ toArray a4
I would envision something like
runFn someFn <$> fmap toArray [a1, a2, a3, a4]
In that case runFn someFn would create a partially applied function that awaits its missing parameters and gets then applied one by one on the elements of the array.
I must admit I dont know if the type system will allow for this.
Edit
As it was asked for - here the actual type signatures for this.
However my question is a more general one:
Can I put the parameters of an function into an array if those parameters are of the same type and the partially apply the function array element by array element.
type Numbers = Array Number
foreign import _intersect :: Numbers -> Numbers -> Numbers -> Numbers -> Point2D
data Point2D = Point2D Number Number
toArray :: Point2D -> Numbers
toArray (Point2D x y) = [x, y]
a1 = Point2D 0.5 7.0
a2 = Point2D 3.0 5.1
b1 = Point2D 2.5 9.0
b2 = Point2D 2.1 3.6
intersection :: Numbers -- 2 element Array Number
intersection = _intersect (toArray a1) (toArray a2) (toArray b1) (toArray b2)
If I understand what you're asking here, no you can't. You'd need dependant types to be able to express this, as you'd need some way of ensuring the function arity and array length are equal at the type level.
If we are allowed to change the question slightly, we might be able to achieve what I think you want. The fact that all functions are curried allows us to use type class instance resolution to come up with some tricks that sort of allow us to do things with functions of arbitrary arity. For example:
module Main where
import Prelude
import Data.Foldable (sum)
import Control.Monad.Eff.Console (print)
class Convert a b where
convert :: a -> b
data Point2D = Point2D Number Number
type Numbers = Array Number
instance convertId :: Convert a a where
convert = id
instance convertPoint :: Convert Point2D (Array Number) where
convert (Point2D x y) = [x, y]
instance convertChain :: (Convert b a, Convert r r') => Convert (a -> r) (b -> r') where
convert a2r b = convert (a2r (convert b))
f :: Numbers -> Numbers -> Number
f xs ys = sum xs * sum ys
g :: Point2D -> Point2D -> Number
g = convert f
f' :: Numbers -> Numbers -> Numbers -> Numbers -> Number
f' a b c d = f a b + f c d
g' :: Point2D -> Point2D -> Point2D -> Point2D -> Number
g' = convert f'
main =
print $ g'
(Point2D 1.0 2.0)
(Point2D 3.0 4.0)
(Point2D 5.0 6.0)
(Point2D 7.0 8.0)
These techniques have some nice applications. QuickCheck, for example, uses a similar technique to allow you to call quickCheck on functions of any arity, as long as all the arguments have Arbitrary instances. In this specific case, though, I think I would stick to the simpler, more boilerplate-y solution: unrestrained use of type classes can become quite unwieldy, and can produce very confusing error messages.
Let's say I have a type declaration:
data MyType = N Double | C Char | Placeholder
I want to be able to treat MyType as a Double whenever it's possible, with all the Num, Real, Fractional functions resulting in N (normal result) for arguments wrapped in the N constructor, and Placeholder for other arguments
> (N 5.0) + (N 6.0)
N 11.0
> (N 5.0) + (C 'a')
Placeholder
Is there a way to do this other than simply defining this class as an instance of those classes in a manner similar to:
instance Num MyType where
(+) (N d1) (N d2) = N (d1+d2)
(+) _ _ = Placeholder
...
(which seems counter-productive)?
There is no generic deriving available in standard Haskell: currently, deriving is only available as defined by the compiler for specific Prelude typeclasses: Read, Show, Eq, Ord, Enum, and Bounded.
The Glasgow Haskell Compiler (GHC) apparently has extensions that support generic deriving. However, I don't know if it would actually save you any work to try and use them: how many typeclasses do you need to derive a Num instance from? And, are you sure that you can define an automatic scheme for deriving Num that will always do what you want?
As noted in the comments, you need to describe what your Num instance will do in any case. And describing and debugging a general scheme is certain to be more work than describing a particular one.
No, you can't do this automatically, but I think what leftaroundabout could have been getting at is that you can use Applicative operations to help you.
data MyType n = N n | C Char | Placeholder deriving (Show, Eq, Functor)
instance Applicative MyType where
pure = N
(<*>) = ap
instance Monad MyType where
N n >>= f = f n
C c >>= _ = C c
Placeholder >>= _ = Placeholder
Now you can write
instance Num n => Num (MyType n) where
x + y = (+) <$> x <*> y
abs = fmap abs
...
Is there a standard specialization of Either in Haskell or Scala that makes the types contained in the Left and Right the same type?
In Haskell, I want something like this:
data SpecializedEither a = Left a | Right a
This might also be considered a slight generalization of Maybe that makes Nothing hold a value.
edit: Ganesh raises a very good point that a Monad instance can't be defined for this type. Is there a better way to do what I am trying to do?
There's a standard Monad instance on ((,) e) so long as e is a Monoid
instance Monoid e => Monad ((,) e) where
return a = (mempty, a)
(e1, a) >>= f = let (e2, b) = f a in (e1 <> e2, b)
Since Either a a and (Bool, a) are isomorphic (in two ways), we get a Monad instance as soon as we pick a Monoid for Bool. There are two (really four, see comments) such Monoids, the "and" type and the "or" type. Essentially, this choice ends up deciding as to whether the Left or Right side of your either is "default". If Right is default (and thus Left overrides it) then we get
data Either1 a = Left1 a | Right1 a
get1 :: Either1 a -> a
get1 (Left1 a) = a
get1 (Right1 a) = a
instance Monad Either1 where
return = Right1
x >>= f = case (x, f (get1 x)) of
(Right1 _, Right1 b) -> Right1 b
(Right1 _, Left1 b) -> Left1 b
(Left1 _, y ) -> Left1 (get1 y)
How about:
type Foo[T] = Either[T, T]
val x: Foo[String] = Right("")
// Foo[String] = Right()
I make class Expr for arithmetic operations
class Expr a where
mul :: a -> a -> a
add :: a -> a -> a
lit :: Integer -> a
i want to "parse" something like this: mul ( add (lit 3) (lit 2)) (lit 4) = (3+2)*4
and i have data type:
data StackExp = PushI Integer
| PushB Bool
| Add
| Mul
| And
| Or
deriving Show
and
type Program = [StackExp] --i use this type for function of stack calculator later
my task is: i need to make instance of Expr for type Program
more concrete - i want to make this transformation:
mul ( add (lit 3) (lit 2)) (lit 4) ->>> [PushI 2, PushI 3, Add, PushI 4, Mul]
i have problems because i receive [[StackExp]] at the output of my instance declaration.
my try:
instance Expr Program where
lit n = (PushI n):[]
add exp1 exp2 = exp1:(exp2:[Add])
mul exp1 exp2 = exp1:(exp2:[Mul])
i don't know how to concatenate all sub-expressions into list
---------------- compiler error looks like this------------------------
Couldn't match type `[StackExp]' with `StackExp'
Expected type: StackExp
Actual type: Program
..........
So, what you basically want to do is you want to compile from the abstract syntax of your expression language (the type class Expr) to code for a simple stack machine (a list of elements of type StackExpr).
One problem that you immediately run into then is that, in just Haskell 98 or Haskell 2010, you cannot declare [StackExpr] an instance of a class. For example, GHC will complain with
Illegal instance declaration for `Expr [StackExp]'
(All instance types must be of the form (T a1 ... an)
where a1 ... an are *distinct type variables*,
and each type variable appears at most once in the instance head.
Use -XFlexibleInstances if you want to disable this.)
In the instance declaration for `Expr [StackExp]'
To work your way around this, you could define Program as a type isomorphism (rather than as a mere type synonym as you have now):
newtype Program = P [StackExp] deriving Show
and then make Program an instance of the class Expr. (Alternatively, you could enable FlexibleInstances as suggested by the error message above.)
Now we can write the required instance declaration:
instance Expr Program where
mul (P x) (P y) = P (x ++ y ++ [Mul])
add (P x) (P y) = P (x ++ y ++ [Add])
lit n = P [PushI n]
That is, for multiplication and addition, we first compile the operands and then produce, respectively, the Mul or Add instruction; for literals we produce the corresponding push instruction.
With this declaration, we get, for your example:
> mul (add (lit 3) (lit 2)) (lit 4) :: Program
P [PushI 3,PushI 2,Add,PushI 4,Mul]
(Not quite as in your example. You swap the order of the operands to Add. As addition is commutative, I will assume that this version is acceptable as well.)
Of course it is more fun to also write a small evaluator for stack programs:
eval :: Program -> [Integer]
eval (P es) = go es []
where
go [] s = s
go (PushI n : es) s = go es (n : s)
go (Add : es) (m : n : s) = go es ((m + n) : s)
go (Mul : es) (m : n : s) = go es ((m * n) : s)
(Note that I am ignoring instructions that deal with Booleans here as you only seem to deal with integer expressions anyway.)
Now we have, for your example,
> eval (mul (add (lit 3) (lit 2)) (lit 4))
[20]
which seems about right.
I have to implement the Map function using only the foldRight, foldLeft and unfold. This means that I have to loop through every element in the list and apply a function f to it.
I have declared my own list as follow:
abstract class IntList
case class Nil() extends IntList
case class Cons(h: Int, t: IntList) extends IntList
And I've implemented the foldRight, foldLeft and unfold functions.
and the implementation of the new map function:
def map(ls: IntList, f: Int => Int): IntList = // ??
I've been thinking for a while now, but I don't have a clue where to begin. I may not use recursion in the map function. I'm pretty sure that I have to combine the power of fold and unfold together. Unfold returns a IntList, which is the return type of map. But I'm not sure what I have to give with this function.
Anyone has a clue? :)
Match the types, fill in the arguments to match.
For instance, if you are going to use foldRight, then B must be IntList, because that's the type returned by map. Now fill in the arguments to foldRight with whatever values you have that match the types.
[In reply to previous comments.]
I don't know which exact variant of unfold you are given. Assuming it's something like this (in Ocaml, sorry, don't have Scala installed right now):
(* unfold : ('a -> ('b * 'a) option) -> 'a -> 'b list *)
let rec unfold f x =
match f x with
| None -> []
| Some (y, x') -> y :: unfold f x'
Then a solution for map is the following:
let map f = unfold (function [] -> None | x::xs -> Some (f x, xs))
Hope that helps.