how to create a lazy tree in Standard ML - sml

I want to implement a lazy tree in Standard ML with
datatype tr = N of int * unit->tr * unit->tr;
I tried to use
fun form k = N(k,fn()=>form(k+1),fn()=>form(k+3));
as a test of concept, but I get error message saying type mismatch.
What would be the proper way of implementing a lazy tree in ML?

datatype tr = N of int * unit->tr * unit->tr;
This is parsed as
datatype tr = N of (int * unit) -> ( (tr * unit) -> tr)
You want
datatype tr = N of int * (unit->tr) * (unit->tr)

Related

SML create a list of lists operand mismatch

I am trying to create a list of lists meaning my result should be like
thatgraph = [[0,[1,2]],[1,[1,3],[1,4],[1,5]],[2,[3,4],[4,4],[5,5],[5,10]]
The code i use is :
fun pin2graph (pin,thatgraph,i,j,rows,cols,havepizza) =
if (i<rows) andalso (j<cols-1) then
(
pin2graph (pin,thatgraph::((i*cols+j),(getAdjacent (pin,i,j,rows,cols,havepizza))),i,j+1,rows,cols,havepizza)
)
else if (i<rows) then
(
pin2graph (pin,thatgraph::((i*cols+j),(getAdjacent (pin,i,j,rows,cols,havepizza))),i+1,0,rows,cols,havepizza)
)
else thatgraph
The getadjacent function is of type :
val getAdjacent = fn
: char Array2.array * int * int * int * int * 'a -> (int * 'a) list
the 'a is actually a real number so the real type is (int * real) list .
Whatever i have tried i always get an operand and operator mismatch with most common being :
operator domain: _ * _ list
operand: _ * (int * (int * 'Z) list)
Any hint would be greatly appreciated , running out of ideas

convert a few 2-tuples to a list of lists

this is a question about ocaml lists and tuples. I have some 2-tuples of numbers (either integers or floats) and I want to convert it to a list of lists (with 2 elements). Assuming that I have defined a num type Int of int | Float of float, the conversion should give the following:
((1,1.0),(0.4,1),(0,0)) => [[Int 1;Float 1.0];[Float 0.4; Int 1];[Int 0;Int 0]]
or more precisely
let a = (1,1.0) and b = (0.4,1) and c = (0,0) in
myconversion (a,b,c) ;;
=> [[Int 1;Float 1.0];[Float 0.4; Int 1];[Int 0;Int 0]]
the point being the values a, b, c... are defined in several places in the source files (by people who use different signatures for their tuples).
The difficulty here is that I don't know the types of the elements of the 2-tuples (int or float, that varies depending on the tuple).
Your input data can't be represented in OCaml as you describe it. OCaml is strongly typed. For example, your example input list is an invalid value in OCaml:
# [(1,1.0);(0.4,1);(0,0)];;
Error: This expression has type float but an expression was expected of type
int
So what you describe as the essence of your problem (not knowing the types) is in fact not possible. You'll have to use some other method of representing the input. For example, you could just use floats for everything. Or you could use pairs of strings.
Update
The answer for the rewritten question is the same. In OCaml it's not possible not to know the type of something statically; i.e., at the time you're writing the program (unless it can be any type at all). It's not possible (or necessary) to query the type of something at runtime. So your question doesn't have an answer (at least as far as I can see).
For OCaml, you have to think with the type system rather than against it. After a while you start to really like it (or at least that's how it worked for me). I'd start by writing down the type you want your function myconverstion to have.
Update 2
I'll repeat my advice to treat your inputs as strings. Assuming you've parsed your input up into pairs of strings, here's some code that does what you want:
let myconversion coords =
let c1 s =
if String.contains s '.' then
Float (float_of_string s)
else
Int (int_of_string s)
in
let cp (a, b) = [c1 a; c1 b] in
List.map cp coords
Here's how it works for your input (reinterpreted as strings):
# myconversion [("1", "1.0"); ("0.4", "1"); ("0", "0")];;
- : fi list list = [[Int 1; Float 1.]; [Float 0.4; Int 1]; [Int 0; Int 0]]
Update 3
Here's some (crude) code that parses a file of numbers into coordinates represented as pairs of strings. It should work as long as the tuples in the input are well formed.
let coords fname =
let ic = open_in fname in
let len = in_channel_length ic in
let buf = Buffer.create 128 in
let () = Buffer.add_channel buf ic len in
let () = close_in ic in
let s = Buffer.contents buf in
let nums = Str.(split (regexp "[^0-9.]+") s) in
let rec mkcoords sofar = function
| [] | [_] -> List.rev sofar
| a :: b :: rest -> mkcoords ((a, b) :: sofar) rest
in
mkcoords [] nums
There are two distinct problems in your setup:
you don't know the type of the tuples parameters
you want to pass them as a single n-ary tuple
For problem 2, you would have to write a function for that type specifically, whereas you could mimic a type level list type by nesting couple of tuples:
myconversion a,(b,c) ;;
The reason is that with that setup, you could write a recursive polymorphic function on the type level list:
val myconversion : type a b. (a,b) -> num list
There would still be a problem on the last element though.
So, assuming that you could pass a sequence to your conversion function, and have it process elements of that sequence one by one, you would still need to find a way of selecting the proper function of pair conversion from the tuple type: that's basically ad-hoc polymorphism, ie. you would need to be able to overload a function on its parameters' types(1). Unfortunately, OCaml doesn't support that out of the box.
One possibility would be perhaps (I have no experience doing that) to implement an extension which would extract the type information of a given expression, and generate the correct code to process it in your own code.
A flexible technique consists in having that extension generate an algebraic description of the tuples types, and use that description as an equality witness in the code which will process the tuples:
type _ w =
| U : (unit * unit) w
| IF : 'a w -> ((int * float) * 'a) w
| FI : 'a w -> ((float * int) * 'a) w
(* other constructors if necessary *)
(* data *)
let a = 1,1.0
let b = 2.0, 2
let c = 3.0, 3
let d = 4, 4.0
let l = a,(b, (c,(d,((),()))))
(* witness *)
let w = IF (FI (FI (IF U)))
(* the type parameter of w should be the same as l type *)
let rec conv : type a b. (a * b) w -> (a * b) -> num list = fun w (x, xs) ->
match w with
U -> []
| IF w' -> let i,f = x in (Int I)::(Float f)::(conv w' xs)
(* etc *)
Here, we encode the type level nil list as (unit * unit) w.
A coalgebraic approach would require to register function overloads to the conversion function polymorphic signature within the extension, and let it pick the right one from the function overload dictionary.
There's a discussion on that topic on the LtU site.
Thanks to everybody who answered. I finally found a solution, using a bit of magic:
# type num = Int of int | Float of float;;
# let to_num x = if Obj.is_int (Obj.repr x) then
Int (Obj.magic (Obj.repr x) : int)
else
Float ((Obj.magic (Obj.repr x) : float));;
# let pair_to_num (a,b) = [to_num a; to_num b];;
# let myconversion (a,b,c) = [pair_to_num a; pair_to_num b; pair_to_num c];;
and the test:
# myconversion ((1,1.0),(0.4,1),(0,0));;
- : num list list = [[Int 1; Float 1.]; [Float 0.4; Int 1]; [Int 0; Int 0]]
# myconversion ((0,0),(1,1.0),(0.4,1));;
- : num list list = [[Int 0; Int 0]; [Int 1; Float 1.]; [Float 0.4; Int 1]]
Magic, the order does not matter and the type is recorded! I can then follow didier's idea to get rid of the pair of superfluous parentheses.

Haskell Tree With Function Branches

I'll start of by saying I'm very new to Haskell, so I haven't learned about things like Monads yet.
In Haskell I'm trying to make a type of tree that has numbers as the leaves and functions as the branches so the whole tree can act kind of like a calculator.
Here's my code so far. Currently instead of having functions as an input I'm just using characters.
data Tree3 = Leaf3 Int | Node3 Char Tree3 Tree3 deriving (Show)
-- I would like to replace this ^ Char somehow with a function.
evaluate :: Tree3 -> Int
evaluate (Leaf3 x) = x
evaluate (Node3 c m n) | c == '+' = evaluate m + evaluate n
| c == '-' = evaluate m - evaluate n
| c == '/' = evaluate m `div` evaluate n
| c == '*' = evaluate m * evaluate n
So my question is can I have an input of a function in the data structure (and what would the type be?)
Sorry for the probably confusing question, but thanks for any advice!
I would recommend writing your tree as:
data Tree = Leaf Int | Node (Int -> Int -> Int) Tree Tree
Note that you won't be able to derive Eq or Show, since Int -> Int doesn't implement either of those typeclasses (and it's impossible impractical to do so).
Then you can write your evaluate function as
evaluate :: Tree -> Int
evaluate (Leaf x) = x
evaluate (Node f l r) = f (evaluate l) (evaluate r)
which is much simpler!
You can make a tree to represent an expression like (1 + 2) * (3 * 4) as
expr :: Tree
expr = Node (*) (Node (+) (Leaf 1) (Leaf 2)) (Node (*) (Leaf 3) (Leaf 4))
Another way that would make it easier to prettier print your tree would be to use almost the same definition you have:
data Tree = Leaf Int | Node String Tree Tree
-- ^ String instead of Char
Then if you have Data.Map imported, you can create a map of functions to look up, but it makes your evaluate function a bit more complex since you introduce the possibility that your function won't be in your map. Luckily Haskell has some really handy tools for handling this elegantly!
import qualified Data.Map as Map
type Tree = Leaf Int | Node String Tree Tree deriving (Eq, Show)
type FuncMap = Map.Map String (Int -> Int -> Int)
evaluate :: FuncMap -> Tree -> Maybe Tree
evaluate funcs (Leaf x) = return x
evaluate funcs (Node funcName left right) = do
-- Use qualified import since there's a Prelude.lookup
f <- Map.lookup funcName funcs
l <- evaluate funcs left
r <- evaluate funcs right
return $ f l r
This will automatically result in Nothing if you try something like
evaluate (Map.fromList [("+", (+))]) (Node "blah" (Leaf 1) (Leaf 2))
since the function "blah" isn't in your FuncMap. Notice how we didn't have to do any explicit error handling of any kind thanks to Maybe's monad instance! If any of the lookups to the function map return Nothing, the whole computation returns Nothing without us having to think about it.

How to supply function arguments from a list?

Assume I have a function f that takes n arguments of the same type f: 'a * 'a * ... * 'a -> 'b
Assume I have a list lof n 'a elements,
Does the functor call_function_with_list exist? It would mean this:
call_function_with_list f l = f l[0] l[1] ... l[n-1]
Observe that I am not interested in specifying a particular call_function_with_list for a fixed number n (which could be done quite simply) but I am interested in having a general call_function_with_list that works for all n
You can't (without resorting to the dark magic of the Obj module, that is). Indeed, there are two issues. First OCaml's type system cannot represents something like 'a list -> ('a * 'a * ... * 'a) where ... actually depends on the length of the argument (you could do something like that in Coq for instance). Second, in OCaml an n-uple is not an iterated version of a pair, i.e. a value of type 'a * 'a * 'a is neither a value of type 'a * ('a * 'a) nor of type ('a * ('a * 'a)), so that you cannot build your nuple step by step from the elements of the list.
# let x = (1,2,3);;
val x : int * int * int = (1, 2, 3)
# let y = (1,(2,3));;
val y : int * (int * int) = (1, (2, 3))
# let z = (1,2),3;;
val z : (int * int) * int = ((1, 2), 3)
# x = y;;
Error: This expression has type int * (int * int)
but an expression was expected of type int * int * int
# x = z;;
Error: This expression has type (int * int) * int
but an expression was expected of type int * int * int

unfolding lists in ML

hello everyone I'm trying to write function which can unfold int in the list from any depth, for example if I have following bigList: [12, [34], [11,[1]]] I want to receive
[(1,12),(2,34),(3,11),(4,1)]
first element in tuple is the depth and the second is the number
I wrote this code:
datatype 'a bigList = Empty of unit
| Element of 'a
| List of 'a bigList list;
local
fun unfolder( Empty , n ) = []
| unfolder( (Element l)::ls, n ) = (n, l)::unfolder( ls, n )
| unfolder( (List l)::ls, n) = unfolder( l, n + 1)::unfolder(ls, n)
in
fun flat list = unfolder(list, 1)
end;
every time I receive the following error:
Standard ML of New Jersey v110.71 [built: Thu Sep 17 08:50:14 2009]
- datatype 'a bigList = Element of 'a | Empty of unit | List of 'a bigList list
stdIn:9.5-11.69 Error: data constructor Empty used without argument in pattern
stdIn:11.33-11.69 Error: operator and operand don't agree [tycon mismatch]
operator domain: (int * 'Z) list * (int * 'Z) list list
operand: (int * 'Z) list * (int * 'Z) list
in expression:
unfolder (l,n + 1) :: unfolder (ls,n)
-
thanks in advance for any help
data constructor Empty used without argument in pattern
You defined Empty as Empty of unit, which means you need to use it as Empty (), which is pretty pointless. To use it as just Empty, you need to define it as Empty without the of unit.
unfolder (l,n + 1) :: unfolder (ls,n)
The type of :: is 'a * ['a] -> ['a], which means that the left operand must be a single element and the right operand a list. In the above both operands are a list, so you get a type error.
To concatenate two lists use the # operator, not ::.