ML Functions with Real Numbers - numbers

I am new to ML and have been trying simple functions, but I am having trouble trying to get functions to work with real numbers. For example, this reverse function....
fun reverse (nil) = nil
| reverse (x::xs) = if xs = nil then [x]
else (reverse xs) # [x];
I get the propper output for integers and strings.
- reverse [1,2,3,4];
val it = [4,3,2,1] : int list
- reverse ["a" , "b" , "c" , "d" ];
val it = ["d","c","b","a"] : string list
Can anyone explain to me why this function will not work with real numbers?
Here is the output when I try reals...
- reverse [1.0, 2.0];
stdIn:1.2-53.9 Error: operator and operand don't agree [equality type required]
operator domain: ''Z list
operand: real list
in expression:
reverse (1.0 :: 2.0 :: nil)

real is not an equality type in ML, and so neither are polymorphic types constructed from reals -- in particular, real lists are not equality types, and so you cannot use the operator = to compare two real lists, even if those lists are empty. Instead, you need to pattern match. For example,
fun reverse [] = []
| reverse (x::xs) = (reverse xs) # [x]
or
fun reverse [] = []
| reverse (x::xs) = case xs of
[] => [x]
| _ => (reverse xs) # [x]
will work even for nonequality types.
(Alternately, use the built in function List.rev.)

Related

multiplication of two binary numbers

I need to do the function that multiplicates two binary numbers represented by a list of booleans.
Here what I wrote :
Fixpoint brmul_r (x y res: list bool): list bool :=
match x,y,res with
|x,y,res-> if value x >0 then res else if (value x) mod 2 = 0 then brmul_r ((value x/2) (value y*2) (badd res y))
else brmul_r (x y*2 res)
end.
but it doesn't work.. what should I do?
Thank you in advance!
There are many problems with that code:
Syntax error: you want to use => instead of -> inside the match.
Actually, you are not taking advantage of the patter matching, so you can remove it entirely and start your definition with if ....
Then Coq complains that _ > _ has type Prop. You need to use the boolean version _ <? _ instead, and the same for the equality later: _ =? _ instead of _ = _.
In brmul_r ((value x/2) (value y*2) (badd res y)), the outer brackets are not supposed to be there; brmul_r is supposed to receive three arguments, not one argument, and similarly for brmul_r (x y*2 res)
What do you mean by value x/2? Is it value (x / 2) or (value x) / 2? The former does not type-check unless you redefined the _ / _ notation to work over lists of booleans. But the latter has type nat, and brmul_r expects something of type list bool, so it doesn't work either. A similar observation holds for value y*2.
This is not something Coq complains about yet (the problem in 5 would have to be solved first), but it will not be clear for Coq that your definition terminates, since you are using brmul_r to define brmul_r and feeding it non-structurally decreasing arguments. In fact, you even feed it increasing arguments in the final branch (I'm talking about brmul_r x y*2 res).
So what should one do? Convincing Coq that the function terminates is the real issue here, the rest is just confusion over syntax. Since this is a function on lists, it should recurse on the list structure, so it should have the following basic shape (I am assuming the context of Require Import List. Import ListNotations.):
Fixpoint brmul_r (xs ys : list bool) : list bool :=
match xs with
| [] => (* TODO *)
| hd :: tl => (* TODO *)
end.
Assuming the first element of the list is the least significant bit, it will be useful to match on it as well, so the structure becomes:
Fixpoint brmul_r (xs ys : list bool) : list bool :=
match xs with
| [] => (* TODO *)
| false :: tl => (* TODO *)
| true :: tl => (* TODO *)
end.
Now the goal is to express the product of false :: tl with ys when we already know the product of tl with ys. Translating to numbers (for intuition's sake), we want to find (2 * (value tl)) * (value ys) when we already know how to compute (value tl) * (value ys). Putting it like this, it becomes clear that we just need to duplicate the result of the latter. Going back to our list representation, we observe that duplicating corresponds to preppending false, so we can update our definition as follows:
Fixpoint brmul_r (xs ys : list bool) : list bool :=
match xs with
| [] => (* TODO *)
| false :: tl => false :: brmul_r tl ys
| true :: tl => (* TODO *)
end.
Now you can use the same reasoning to complete the function.
For the future:
Please include the necessary context. In this case it would be the modules you imported and the custom defined functions such as value.
It might be useful to follow a Coq tutorial to help with all the syntax issues and with the intuitions behind recursive and functional programming. Software Foundations is very good. There are also others.
There is now a dedicated Stack Exchange site for Proof Assistant-related questions.

How to check if a value exists in a list in smlnj

I'm working on some homework and I need to create a function that checks if a value exists in a list. If it does it will return true, otherwise it returns false. I have an idea of how to do it but I keep getting errors. I think it may be due to my lack of knowledge of syntax and style as this is my first time coding in sml.
I created the function exist and am passing a value and list in as a tuple.
fun exist (x, []) =
if x = hd ([]) then true
else if x = tl ([]) then true
else false;
Sorry if this code is laughably incorrect but I get the error message:
" stdIn:2.6 Warning: calling polyEqual
stdIn:3.11 Warning: calling polyEqual
stdIn:1.6-4.11 Warning: match nonexhaustive
(x,nil) => ...
val exist = fn : ''a list * 'b list -> bool "
and I'm not really sure how to fix this. Any help would be great.
Your function is pattern-matching on [], so it can only ever match the empty list.
Also, hd [] and tl [] are both errors since the empty list has neither head nor tail.
Further, if some_condition then true else false is equivalent to some_condition.
(And if some_condition then false else true is equivalent to not some_condition.)
Logical expressions are usually more readable than chains of conditionals.
And you forgot to recurse; you need to use exist on the tail of the list if the first element is not what you're looking for.
Either stick to pattern matching:
fun exist (_, []) = false
| exist (x, y::ys) = x = y orelse exist (x, ys)
or don't use it:
fun exist (x, xs) = not (null xs) andalso (x = hd xs orelse exist (x, tl xs))
Pattern matching is often the most readable solution and gives a clear picture of the various cases.
(You seem to have mixed the two forms, treating [] as an identifier rather than a type constructor.)

How to use Socket.select

How do I go about using Socket.select in Standard ML?
According to the docs, I'm supposed to pass it three lists of sockets and a timeout option, and the function returns when any of the sockets are ready to do something (and I assume, but don't know for sure that the sockets in the out list are only the ones that need attention). However,
The input seems to be neither a tuple, nor four arguments. How do I go about constructing an appropriate input structure?
select takes and returns lists of sock_desc, and there doesn't seem to be a way of getting a socket back from its sock_desc. There also doesn't seem to be a way of constructing an efficient map, since it doesn't seem to be possible to order two sock_descs, merely compare them for equality. Once I've got the return value from select, how do I do anything useful with the returned sockets, such as write responses out, or call accept on them?
The input argument is a record with four fields, so your code should look something like this:
Socket.select {
rds = readSocketDescs,
wrs = writeSocketDescs,
exs = exnSocketDescs,
timeout = SOME (Time.fromSeconds 10)
}
Yeah, not sure, probably you need to keep a mapping yourself using lists. Not very efficient, but I can't see what else you can do.
(**
* Produces a list of all the pairs in `listPair`, whose keys are present
* in `whiteList`. Example:
*
* ```sml
* - filterListPair op= [(1,"a"), (2,"b"), (3,"c")] [2,3];
* val it = [(2,"b"),(3,"c")] : (int * string) list
* ```
*)
fun filterListPair eq listPair whiteList =
let
fun recur listPair whiteList result =
case (listPair, whiteList) of
([], _) => result
| (_, []) => result
| ((x, y) :: xs, k :: ks) =>
if eq (x, k)
then recur xs ks ((x, y) :: result)
else recur xs whiteList result
in
List.rev (recur listPair whiteList [])
end
val sockets = [ (* what have you *) ]
val descsToSockets = List.map (fn s => (Socket.sockDesc s, s)) sockets
val { rds, wrs, exs } = Socket.select {
rds = readSocketDescs,
wrs = writeSocketDescs,
exs = exnSocketDescs,
timeout = SOME (Time.fromSeconds 10)
}
(*
* The contract of Socket.select ensures that the order in input lists
* is preserved in the output lists, so we can use `filterListPair`.
*)
val selectedReadSockets =
filterListPair Socket.sameDesc descsToSockets rds

simple function to return list of integers

if am trying to write a simple function that list of pair of integers - representing a graph and returns a list of integers : all the nodes in a graph
eg if input is [(1,2) (3,4) (5,6) (1,5)]
o/p should be [1,2,3,4,5,6,1,5]
The function is simply returning list of nodes , in the returning list values may repeat as above.
I wrote the following function
fun listofnodes ((x:int,y:int)::xs) = if xs=nil then [x::y] else [[x::y]#listofnodes(xs)]
stdIn:15.12-15.18 Error: operator and operand don't agree [tycon mismatch
operator domain: int * int list
operand: int * int
in expression:
x :: y.
I am not able to figure out what is wrong.
first of all you should know what each operator does:
:: puts individual elemtents into an existing list so that: 1::2::3::[] = [1,2,3]
# puts two lists together so that: [1,2] # [3,4] = [1,2,3,4]
you can also use :: to put lists together but then it becomes a list of lists like:
[1,2] :: [3,4] = [[1,2],[3,4]]
so by writing [x::y] you are saying that x and y should become a list inside a list.
and you shouldnt use an if statement to check for the end of the list, instead you can use patterns to do it like this:
fun listofnodes [] = []
| listofnodes ((x,y)::xs) = x :: y :: listofnodes(xs);
the first pattern assures that when we reach the end of the list, when you extract the final tuple your xs is bound to an empty list which it calls itself with, it leaves an empty list to put all the elements into, so that [(1,2) (3,4) (5,6) (1,5)] would evaluate like this:
1 :: 2 :: 3 :: 4 :: 5 :: 6 :: 1 :: 5 :: [] = [1,2,3,4,5,6,1,5].
you could also make it like this:
fun listofnodes [] = []
| listofnodes ((x,y)::xs) = [x,y] # listofnodes(xs);
this way you make a small 2 element list out of each tuple, and then merge all these small lists into one big list. you dont really need the empty list at the end, but its the only way of ensuring that the recursion stops at the end of the list and you have to put something on the other side of the equals sign. it evaluates like this:
[1,2] # [3,4] # [5,6] # [1,5] # [] = [1,2,3,4,5,6,1,5].
also you cast your x and y as ints, but you dont really have to. if you dont, it gets the types " ('a * 'a) list -> 'a list " which just means that it works for all input types including ints (as long as the tuple doesnt contain conflicting types, like a char and an int).
im guessing you know this, but in case you dont: what you call pairs, (1,2), is called tuples.

haskell class property check

I would like to have a function that checks a property of a class instance:
class ListWithAtLeastOneElement a where
list :: [a]
check :: Bool
check = (length list) >= 1
but I get this error when compiling in GHC:
"The class method 'check' mentions none of the type variables of the class ListWithAtLeastOneElement a When checking the class method: check :: Bool In the class declaration for 'ListWithAtLeastOneElement'"
Is there a better way of doing what I want, or a way to get this to compile in GHC?
You seem to think a class in Haskell is like a class in an OO-language. That is not true. You should use a data type or newtype or type synonym.
newtype NonemptyList a = List1 [a]
fromList :: [a] -> Maybe (NonemptyList a)
fromList [] = Nothing
fromList xs#(_:_) = Just $ List1 xs
check :: NonemptyList a -> Bool
check (List1 xs) = length xs >= 1
As jmg said, this isn't valid Haskell so it's good GHC isn't compiling it! If you're used to Java evidently you should think of Haskell's type classes like Java interface. If that doesn't help then perhaps you should read LYAH's chapter on classes.
For you problem, it appears you're wanting a list-like data type that can never be null. You don't need to test for such a property, you can statically ensure it by using a data
type that can never be empty:
-- Notice this data type can never have zero 'a' values!
data NonEmptyList a = NEL a (NonEmptyList a) | Singleton a
-- We can define basic operators for this, just like list has
-- You can't pattern match with them, but there are work-arounds for that if you want to ask
(.:) = NEL -- concatenate non-empty lists
nelHead :: NonEmptyList a -> a
nelHead (NEL a _) = a
nelHead (Singleton a) = a
nelTail :: NonEmptyList a -> Maybe (NonEmptyList a)
nelTail (NEL _ b) = Just b
nelTail _ = Nothing
nelTake :: Int -> NonEmptyList a -> NonEmptyList a
nelTake 1 (NEL a _) = Singleton a
nelTake 1 (Singleton a) = Singleton a
nelTake n (NEL a rest) = a .: nelTake (n-1) rest
nelDrop :: Int -> NonEmptyList a -> NonEmptyList a
nelDrop _ (Singleton _) = error "Perhaps I should have used the 'maybe' type"
nelDrop 1 (NEL a r) = r
nelDrop n (NEL a r) = nelDrop (n-1) r
And so on and so forth. It's worth noting nelTake and nelDrop are partial but nelHead is total, funny as this is the opposite of regular lists.
You would need to make check a function
check :: [a] -> Bool
That said you are better off with a data type for non-empty lists rather than a class, classes in Haskell do not serve the same purpose as classes in object oriented languages.