Clean - Appending to a list - functional-programming

I am trying to append to a list in the Clean programming language.
This is my code:
import StdEnv
path0 = "urrd"
//path1 = "urdl"
//path2 = "uurrddll"
//path3 = "ururdrdldlul"
Mirror :: [Char] -> [Char]
Mirror [] = []
Mirror str = [(NegatePath last str) : (Mirror init str)]
NegatePath :: Char -> Char
NegatePath 'u' = 'd'
NegatePath 'd' = 'u'
NegatePath 'l' = 'r'
NegatePath 'r' = 'l'
Start = Mirror path0
This is the error I get:
Type error [Homokozoo.icl,13,Mirror]:"argument 1 of list constructor" cannot unify types:
[Char]
{#Char}

I didn't know about the Clean language before reading this question, so this could be way off, but I think I've identified the problem after spending some time scanning chapter 4 of the language report. The problem appears to be that your Mirror function is built to operate on a list of characters [Char] but you are passing it an unboxed array of characters {#Char}.
It might work if you declared
path0 = ['urrd']
so that the type of path0 is a list of characters rather than an unboxed array of characters. If that's not what you want, you may need to modify the Mirror function to work on {Char}.

Related

Converting a list of integers to a map of vertices containing the elements coordinates

This is what i have at the moment
(string -> int list)
let read filename = ....
this is working as intended, returning a list of integers from a textfile looking like this:
530070000
600195000
098000060
800600003
400803001
700020006
060000280
000419005
000080079
Yes you are correct, it is a sudoku board. This is what i have to work with:
type vertex = int * int (*Cells in the sudoku board*)
type gamma = int (*representing colors 1-9*)
(* [Vertex = Map.Make(Vertex)] *)
module Vertex = Map.Make(struct
type t = vertex
let compare = Stdlib.compare
end)
(* [Gamma = Set.Make(Gamma)] *)
module Gamma = Set.Make(struct
type t = gamma
let compare = Stdlib.compare
end)
The gamma set is for solving the sudoku board using graph coloring. I need help understanding how i can convert the list of integers to a suitable map for this kind of task. According to the structure i provided, so i can access each element in the map using it coordinates (x, y). Hope you understand, otherwise i will try to provide more info. I'm reaaally bad at OCaml but trying to learn. I'm sorry for body errors etc, first time posting here.
As far as I can understand your task, the text file contains a grid of digits with the initial disposition for sudoku. So you shouldn't interpret a line in the file as a single integer but rather as a list of integers. You can either change your read function so that it returns int list list instead of int list and then use List.fold_left over the list that will also count the position of an element in the list, but it is tedious. It is much easier to read the grid directly from the file, e.g.,
let read_matrix chan =
let rec loop i j grid =
match input_char chan with
| exception End_of_file -> grid
| '\n' -> loop (i+1) 0 grid
| '0'..'9' as c ->
loop i (j+1) ##
Vertex.add (i,j) (ascii_digit c) grid
| _ -> invalid_arg "invalid input" in
loop 0 0 Vertex.empty
where ascii_digit is defined as,
let ascii_digit c = Char.code c - Char.code '0'
The read_matrix function takes the channel as input so to read the grid from a file you can define,
let matrix_from_file file =
let chan = open_in file in
let r = read_matrix chan in
close_in chan;
r
Hint: you probably also don't want to include positions with 0 in your grid. It is easy to achieve, just add another case to the pattern in the loop function that will skip it, e.g.,
...
| '0' -> loop i (j+1) grid
...

SML Create function receives list of tuples and return list with sum each pair

I'm studying Standard ML and one of the exercices I have to do is to write a function called opPairs that receives a list of tuples of type int, and returns a list with the sum of each pair.
Example:
input: opPairs [(1, 2), (3, 4)]
output: val it = [3, 7]
These were my attempts, which are not compiling:
ATTEMPT 1
type T0 = int * int;
fun opPairs ((h:TO)::t) = let val aux =(#1 h + #2 h) in
aux::(opPairs(t))
end;
The error message is:
Error: unbound type constructor: TO
Error: operator and operand don't agree [type mismatch]
operator domain: {1:'Y; 'Z}
operand: [E]
in expression:
(fn {1=1,...} => 1) h
ATTEMPT 2
fun opPairs2 l = map (fn x => #1 x + #2 x ) l;
The error message is: Error: unresolved flex record (need to know the names of ALL the fields
in this context)
type: {1:[+ ty], 2:[+ ty]; 'Z}
The first attempt has a typo: type T0 is defined, where 0 is zero, but then type TO is referenced in the pattern, where O is the letter O. This gets rid of the "operand and operator do not agree" error, but there is a further problem. The pattern ((h:T0)::t) does not match an empty list, so there is a "match nonexhaustive" warning with the corrected type identifier. This manifests as an exception when the function is used, because the code needs to match an empty list when it reaches the end of the input.
The second attempt needs to use a type for the tuples. This is because the tuple accessor #n needs to know the type of the tuple it accesses. To fix this problem, provide the type of the tuple argument to the anonymous function:
fun opPairs2 l = map (fn x:T0 => #1 x + #2 x) l;
But, really it is bad practice to use #1, #2, etc. to access tuple fields; use pattern matching instead. Here is a cleaner approach, more like the first attempt, but taking full advantage of pattern matching:
fun opPairs nil = nil
| opPairs ((a, b)::cs) = (a + b)::(opPairs cs);
Here, opPairs returns an empty list when the input is an empty list, otherwise pattern matching provides the field values a and b to be added and consed recursively onto the output. When the last tuple is reached, cs is the empty list, and opPairs cs is then also the empty list: the individual tuple sums are then consed onto this empty list to create the output list.
To extend on exnihilo's answer, once you have achieved familiarity with the type of solution that uses explicit recursion and pattern matching (opPairs ((a, b)::cs) = ...), you can begin to generalise the solution using list combinators:
val opPairs = map op+

Higher order function on lists Ocaml

I created a function p that checks if the square of a given value is lower than 30.
Then this function is called in an other function (as argument) to return the first value inside a list with its square less then 30 ( if p is true, basically I have to check if the function p is true or false ).
This is the code :
let p numb =
let return = (numb * numb) < 30 in return
let find p listT =
let rec support p listT =
match listT with
| []-> raise (Failure "No element in list for p")
| hd :: tl -> if p hd then hd
else support p tl in
let ret = support (p listT) in ret
let () =
let a = [5;6;7] in
let b = find p a in print_int b
But it said on the last line :
Error: This expression (p) has type int -> bool
but an expression was expected of type int -> 'a -> bool
Type bool is not compatible with type 'a -> bool
However, I don't think I'm using higher order functions in the right way, I think it should be more automatic I guess, or not?
First, note that
let return = x in return
can replaced by
x
Second, your original error is on line 10
support (p listT)
This line makes the typechecker deduce that the p argument of find is a function that takes one argument (here listT) and return another function of type int -> bool.
Here's another way to look at your problem, which is as #octachron says.
If you assume that p is a function of type int -> bool, then this recursive call:
support (p listT)
is passing a boolean as the first parameter of support. That doesn't make a lot of sense since the first parameter of support is supposed to be a function.
Another problem with this same expression is that it requires that listT be a value of type int (since this is what p expects as a parameter). But listT is a list of ints, not an int.
A third problem with this expression is that it only passes one parameter to support. But support is expecting two parameters.
Luckily the fix for all these problems is exremely simple.

Julia convert UInt32 to UInt8 vector

I have the following code and I need to covert several UInt32 variables to UInt8 vectors so then combine them into a single UInt8 vector.
The goal is to take the record I have decoded from a Pcap file and put it into a format that I can append to the end of an existing Pcap file.
The code below takes output from a previous function and returns a hex output of 4 UInt 32's and a vector of UInt8's for the payload.
function pcap_get_record(s::PcapOffline)
rec = PcapRec()
if (!eof(s.file))
rec.ts_sec = s.is_big ? read(s.file, UInt32) : ntoh(read(s.file, UInt32))
rec.ts_usec = s.is_big ? read(s.file, UInt32) : ntoh(read(s.file, UInt32))
rec.incl_len = s.is_big ? read(s.file, UInt32) : ntoh(read(s.file, UInt32))
rec.orig_len = s.is_big ? read(s.file, UInt32) : ntoh(read(s.file, UInt32))
rec.payload = read(s.file, rec.incl_len)
return rec
end
nothing
end
Thanks
Here you are
julia> reinterpret(UInt8, rand(UInt32, 1)) |> Vector
4-element Array{UInt8,1}:
0x4d
0x54
0x34
0xd3
remember to check the byte order.
Update: So I have solved this and I was overthinking what needed to be done.
I just wrote the UInt variable in their raw form and that did the trick.
write(pcap, rec.orig_len) #this is a UInt32
write(pcap, rec.payload) #this is a UInt8 vector
Original:
I was having a hard time making my previous comment readable.
Thanks for the response. I am not however able to get the reinterpret to work with my UInt32 variable.
a = reinterpret(UInt8, rec.ts_usec) |> Vector
ERROR: bitcast: argument size does not match size of target type
Stacktrace:
[1] reinterpret(::Type{UInt8}, ::UInt32) at .\essentials.jl:370
[2] top-level scope at none:0
typeof(rec.ts_usec)
UInt32
after messing around some more I was able to get this to work but this doesn't seem very efficient.
"Edit" I just found that this wont work since it cuts off any leading zeros in the UInt32. example rec.incl_len = 0x00000516 would come out as "516" instead of "00000516" which is needed.
julia> hex(n) = string(n, base = 16, pad = 2)
julia> a = hex2bytes(hex(rec.ts_sec))
4-element Array{UInt8,1}:
0x5b
0x60
0xa3
0xa1

Binary trees as innested pairs

I'm trying to represent a generic binary tree as a pair.
I'll use the SML syntax as example. This is my btree type definition:
datatype btree = leaf | branch of btree*btree;
So, I'd like to write a function that, given a btree, print the following:
bprint leaf = 0
bprint (branch (leaf,leaf)) = (0,0)
bprint (branch (leaf, branch (leaf,leaf))) = (0, (0, 0))
and so on.
The problem is that this function always return different types. This is obviously a problem for SML and maybe for other functional languages.
Any idea?
Since all you want to do is to print the tree structure to the screen, you can just do that and have your function's return type be unit. That is instead of trying to return the tuple (0, (0, 0)) just print the string (0, (0, 0)) to the screen. This way you won't run into any difficulties with types.
If you really do not need a string representation anywhere else, as already mentioned by others, just printing the tree might be the easiest way:
open TextIO
datatype btree = leaf | branch of btree * btree
fun print_btree leaf = print "0"
| print_btree (branch (s, t)) =
(print "("; print_btree s; print ", "; print_btree t; print ")")
In case you also want to be able to obtain a string representing a btree, the naive solution would be:
fun btree_to_string leaf = "0"
| btree_to_string (branch (s, t)) =
"(" ^ btree_to_string s ^ ", " ^ btree_to_string t ^ ")"
However, I do not really recommend this variant since for big btrees there is a problem due to the many string concatenations.
Something nice to think about is the following variant, which avoids the concatenation problem by a trick (that is for example also used in Haskell's Show class), i.e., instead of working on strings, work on functions from char lists to char lists. Then concatenation can be replaced by function composition
fun btree_to_string' t =
let
fun add s t = s # t
fun add_btree leaf = add [#"0"]
| add_btree (branch (s, t)) =
add [#"("] o add_btree s o add [#",", #" "] o add_btree t o add [#")"]
in implode (add_btree t []) end

Resources