Miranda Error cannot unify [[char]] with[char] on line 12 - functional-programming

having a problem with coding with miranda am just a newbie to functional programming so slap me hard if ive dont an easy mistake so i learn
anyway i a getting an error on line 12 with having a problem with unifyin char with char my idea is to check is something is spelt right by filtering it with the dictionary wich would be both an list of words and another list from a file added together
this is my line 12
= [filter (= typed) ((read file) ++ dictionary)]
and this is the rest of my program so far
filename == [char]
word == [ char ]
dictionary :: [ word ]
spell:: filename -> filename -> [ char ]
look:: word -> filename ->[[[ char ]]]
look typed file
= [filter (= typed) ((read file) ++ dictionary)]
dictionary =
["aardvark","bell","camp","dictionary","editor","file","ground",
"grounds","help","intelligent","joint","kettle","light","memory",
"nettle","orange","quite","research","standard","terminal",
"umbrella","violin","water","xenon","yellow","zoo","aaa","abb",
"acc","add","aee"]
so could anyone point out where i'v gone wrong?

I've never used Miranda, but having used Haskell, it looks like the problem is that you're trying to append a string and a list of strings; however, I guess that ++ needs two lists of the same type (as in Haskell):
(++) :: [a] -> [a] -> [a]
But read file is of type [char], and dictionary is of type [[char]].
Trying to substitute these into the type signature for ++ causes the type error:
(++) :: [char] -> [[char]] -> ?? -- type error!!
Maybe you want to split (read file) into words before you append it to dictionary. Then you would be appending [[char]] to [[char]], which will work just fine.
Note I don't know anything about Miranda -- this answer is based on looking at your code, the error message you gave, and my experience with Haskell (where I've made oodles of similar mistakes).

Related

Ocaml - Runtime compilation of code as a string

I want to parse and compile a function that I have written at runtime, for example I have the following string I generated at runtime:
let str = "fun x y z -> [x; y; z;]"
I am looking for something that will allow me to do something similar to:
let myfun = eval str
(* eval returns the value returned by the code in the string so myfun will
have the type: 'a -> 'a -> 'a -> 'a list*)
Is there a way to do that in OCaml? I came across Dynlink but I am looking for a simpler way to do it.
There is no easier solution than compiling the code and Dynlinking the resulting library.
Or equivalently, one can use the REPL, write the string to the file system and them load it with #use.
Depending on your precise use case, MetaOCaml might be an alternative.
Another important point is that types cannot depend on values in a non-dependently typed language. Thus the type of eval needs to be restricted. For instance, in the Dynlinking path, the type of dynamically linked functions will be determined by the type of the hooks used to register them.

Recursion in F# Example

I've started learning F# and following in the footsteps of example problems I've written my own statement. It's simple enough, but I'm getting an error that doesn't exist in similar recursion examples.
My function replace takes a list of integers, an swapVal integer and a newVal integer. It then recurses through the list and changes any 'swapVal' to 'newVal'.
let original = [1;3;1;4;1;6;1;9]
let rec replace list origVal newVal =
match list with //look at list
| [] -> [] //when ls empty, return empty list
| head :: tail when head = origVal -> newVal :: replace tail origVal newVal
//when list is a head attached to a tail, if head = origVal,
//call replace on tail and appead the newVal
|_ :: tail -> replace tail origVal newVal
//head not equal to original value, call replace tail and return result
Calling replace original 1 5 I'm getting the following error Script.fsx(144,9): error FS0039: The value or constructor 'original' is not defined. Searching online like here hasn't turned up any solutions. Even O'Reilly's programming F# says that it could be a scoping problem, but there's no way that scope is my error.
I feel like it could be that f# is typing my arguments incorrectly, but I don't know enough about f# to know how it types. I would cast the arguments to make sure, but I read that it's not possible.
Does anyone see any immediate errors?

Type error when using recursion accumulating lists

A dictionary is a list of pairs. The task is to take a dictionary and return a pair of lists: the keys and values.
I tried to do it iterating (using recursion) over the dictionary and accumulating keys and values in two lists, but I get a type error that baffles me.
Note: I am NOT looking for an alternative solution to the task. I want to understand the error and how to correct it.
Here is the code:
let lists_of_dict dict =
let rec separate dict keys values =
match dict with
[] -> (keys, values)
| (k, v)::t -> separate t k::keys v::values
(* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *)
in
separate dict [] []
(the underlined part is characters 19-47 of line 5)
Here is the error message:
File "lod-problem.ml", line 5, characters 19-47:
Error: This expression has type 'a list
but an expression was expected of type 'b * 'c
I can't understand why Ocaml deduces that type, and how to make it understand that the expression has type ('a list * 'b list) (if I'm not mistaken).
separate t k::keys v::values parses as (separate t k) :: (keys v) :: values, not separate t (k::keys) (v::values) as you intended.
So OCaml sees that you build the result using :: and thus the result is going to be a list (never mind the fact that the arguments for :: also have the wrong type - the type checker never gets that far), but the expected result is a tuple (because that's what the first case produced). So at that point the type checker errors out.

How are bytes represented in a file by Ocaml?

I'm trying to write a function to write a list of bytes to a file (we're writing a parser of the .class file and after some insertions writing the file back.) When my partner wrote the code to read it in, the bytecode list variable is a list of ints. So now I need to convert it to bytes and then write it to a new .class file. Will the representation of the hex numbers be the same essentially so that the new .class file can be processed by the JVM? My functional programming is LISP from a single semester three years ago and a semester of Coq one year ago. Not enough to make me think in functional terms easily.
Your question is, in fact, pretty confusing. Here's some code that reads in the bytes of a file as an int list, then writes the ints back out as bytes to a new file. On a reasonable system (you don't mention your system), this will copy a file exactly so that no program including the JVM can tell the difference.
let get_bytes fn =
let inc = open_in_bin fn in
let rec go sofar =
match input_char inc with
| b -> go (Char.code b :: sofar)
| exception End_of_file -> List.rev sofar
in
let res = go [] in
close_in inc;
res
let put_bytes fn ints =
let outc = open_out_bin fn in
List.iter (fun b -> output_char outc (Char.chr b)) ints;
close_out outc
let copy_file infn outfn =
put_bytes outfn (get_bytes infn)
I tested this on my system (OS X 10.11.2). I don't have any class files around, but the JVM had no trouble running a jarfile copied with copy_file.
The essence of this problem has nothing to do with hexadecimal numbers. Those are a way of representing numbers as strings, which don't appear anywhere. It also has little to do with functional programming, other than the fact that you want to write your code in OCaml.
The essence of the problem is the meaning of a series of bytes stored in a file. At the lowest level, the bytes stored in the file are the meaning of the file. So you can faithfully copy the file just by copying the bytes. That's what copy_file does.
Since you want to change the bytes, you of course need to make sure your new bytes represent a valid class file. Once you've figured out the new bytes that you want, you can write them out with put_bytes (on a reasonable system).

How can I express a type in F# that optionally recurses on itself (infinitely)

As a learning exercise I am trying to implment a parser for the graphviz dot language (The DOT language) using the functional parser library fparsec (FParsec). The language describes graphs.
Looking at the language definition I was compelled to write down the following definition:
let rec pstmt_list = opt(pstmt .>> opt(pchar ';') >>. opt pstmt_list)
Where pstmt and pchar ';' are parsers, .>> and >>. combine an occurence of the left parser with an occurence of the right parser, and opt parsers an optional occurrence of its argument parser as an option value. However this definition does not work complaining "... the resulting type would be infinite ...".
This example is probably most easily understood by taking a look at the DOT language linked above.
I am aware of the following seemingly linked questions:
Are Infinite Types (aka Recursive Types) not possible in F#?
Haskell to F# - declare a recursive types in f#
But my F# knowledge may not be sufficient to translate them yet, if they apply here at all.
FParsec provides special combinators for parsing sequences. Normally you should prefer these combinators to reimplementing them with a recursive function. You can find an overview of the available combinators for parsing sequences here: http://www.quanttec.com/fparsec/reference/parser-overview.html#parsing-sequences
In this example pstmt_list is a sequence of statements separated and optionally ended by semicolons, so you could easily define the parser as
let pstmt_list = sepEndBy pstmt (pstring ";")
The problem is that your pstmt_list parser produces some values of some type, but when you use it in the definition, you wrap the values of this type with additional option type (using the opt combinator).
The F# compiler thinks that the type of the values returned by the parser e.g. 'a should be the same as the wrapped type option 'a (which is, of course, not possible).
Anyway, I don't think that this is quite what you need to do - the .>> combinator creates a parser that returns the result of the second argument, which means that you'll be ignoring all the results of pstmt parsed so far.
I think you probably need something like this:
let rec pstmt_list : Parser<int list, unit> =
parse.Delay(fun () ->
opt(pstmt .>> pchar ';') .>>. opt pstmt_list
|>> (function Some(prev), Some(rest) -> prev::rest
| Some(prev), _ -> [prev]
| _, Some(rest) -> rest
| _ -> [] ))
The additional use of Delay is to avoid declaring a value that refers directly to itself.

Resources