Printing constructor name in SML - sml

I would like to know whether there would be a way to print the name of the constructor of a datatype from a function in SML. I could find ways to do this in Haskell by deriving the datatype from libraries like show but not in SML.
I need this because I have a very large datatype with lots of constructors which needs to pretty print the data from a function.
Hence the below code wouldn't work for me.
fun print (Cons of var) = "cons"

Related

What's the difference between a recursive type and a list?

I'm pretty new to OCaml (currently taking awful classes at uni) and we recently studied recursive types. We were told that we use that to create lists but there already are lists in OCaml so I don't really understand when I should be using one over the other.
example :
(* list made with a recursive type : *)
type int_list =
| None
| Element of int * int_list
(* just a list *)
let int_list2 : int list = []
What's the difference between a recursive type and a list?
"Recursive type" describes a whole category of types whereas list is one specific recursive type. In other words: list is a recursive type, but there are recursive types other than list.
there already are lists in OCaml so I don't really understand when I should be using one over the other.
When you should use int_list over the built-in list type? Never. Your teacher showed you this definition as an example of what recursive types look like, not as something you should actually use.
You would define your own recursive types only when defining something that doesn't already exist in the standard library (except for learning exercises of course).

how to print in ML

I've searched and found several people asking this question, but I can't find an explicit answer.
How can I print a non-string in sml?
For example if I have an instance of an ADT, i.e., of a type declared by datatype, and I would like to print the value for debugging. Am I responsible for writing a function which converts such an object to a string, and then print the string? Or is there some printer library I should use? Or is there some sort of printObject or toString function?
Also how can I print other non-string objects such as true and false?
It would appear that sml knows how to print such objects, because when I compile a file using C-l in emacs, I see output such as the following, showing that sml does know how to print the values.
[opening /Users/jimka/Repos/mciml/ex1.1.sml]
type key = string
datatype tree = LEAF | TREE of tree * string * tree
val empty = LEAF : tree
val insert = fn : key * tree -> tree
val member = fn : key * tree -> bool
val t1 = TREE (LEAF,"a",LEAF) : tree
val t2 = TREE (LEAF,"a",TREE (LEAF,"c",LEAF)) : tree
val t3 = TREE (LEAF,"a",TREE (TREE (LEAF,"b",LEAF),"c",LEAF)) : tree
val it = true : bool
val it = () : unit
How can I print a non-string in sml?
As I understand it, this is not possible (in a portable way). Depending on the implementation you're using it may expose a function that does this.
Also how can I print other non-string objects such as true and false?
Many types with corresponding basis library structures (e.g., int and Int) have a toString function, so you could print a bool b via print (Bool.toString b) and similarity with Int.toString for an int.
Some implementation specific thoughts:
For PolyML, you can use the function PolyML.print to print values of arbitrary types (though you may need to explicitly type annotate; the type of the argument should not have any type variables).
For SML/NJ, you might try taking a look at the approach discussed here https://sourceforge.net/p/smlnj/mailman/message/21897190/, though this seems like more trouble than it's worth.
For MLton, I'm not aware of anything like a polymorphic function, but they have a couple guides on implementing printf or similar.
It looks like Moscow ML supports a function Meta.printVal, but only in an interactive session. I'm not sure what support SML# has for this sort of thing.
Am I responsible for writing a function which converts such an object to a string, and then print the string?
Generally speaking, yes.
It would appear that sml knows how to print such objects
Depending on your SML implementation this is enabled because the REPL has access to more information than a program normally might. For instance, SML/NJ is able to do this because the REPL has access to type information not available elsewhere (for a source, see John Reppy's statements in the linked mailman thread).
You might also find MLton's TypeIndexedValues example page helpful for this sort of thing, though I haven't closely examined it for quality myself.

Appending to list based on condition in OCaml

I'm trying to create a list of unique by appending to a list, but I'm getting this error.
Error: This expression has type 'a list
but an expression was expected of type unit
in_list is a boolean function that checks whether the value is in the list.
if(in_list x seen_list) then print_string("Already found") else seen_list#x in
List.iter uniq check_list;;
It seems like there must be some small syntactic error I need to fix for the append function. Suggestions?
TL;DR: Lists are immutable in OCaml
According to your code, you seem to believe that lists are mutable in OCaml, and they are not. Hence seen_list#x compute a new list but does not change seen_list.
You could change your code to
let uniq seen_list x =
if in_list x seen_list then
(Printf.printf: "uniq: %d: Already seen.\n" x; seen_list)
else x :: seen_list
in
List.fold_left uniq [] check_list
The uniq function maps a list of integers to a list of integers without repetitions, logging the entries it skips.
This code is obviously intended to be learning material, I guess, nevertheless you should be aware that it most likely implements a Shlemiel the painter's algorithm.
This is a type error, not a syntactic error.
An OCaml function must always return a result of the same type. Right now, when the item is in the list your function tries to return a different type than if the item is not in the list.
Specifically, when the item is already there your function calls print_string, which returns (). This is called unit, and is a placeholder representing no interesting value. When the item isn't already there, your function returns a value of type 'a list. Almost certainly what you need to do is to return a list in all cases.
It's hard to say more without seeing more of your code, but the most usual way to handle this situation is to return the old list when the item is already there and a new, longer list when the item isn't already there.
Update
There are many things to fix in this code, but that's the point of the exercise I assume.
Your next problem seems to be that List.iter is an imperative function, i.e., it wants to do something rather than produce a result. Hence the function that it iterates over the list should return unit (described above). You're using the function uniq instead, which returns a list.
If you want to use a higher-order function like List.iter, which is excellent OCaml style, you will need to use a fold (List.fold_left or List.fold_right), whose purpose is to accumulate a result.

Erlang: Printing a List with a name always in front of it

I just started learning Erlang so please bear with me if this question seems a little simple.
Hi guys. I've been thinking about it for a while but nothing I come up with seems to be working.
I am writing an Erlang function that is supposed to take a list as an argument then print the list with my name in front of it. For the purposes of this question, let's say my name is "James".
If I type in testmodule:NameInFront("Legible", "Hey", "Think").
Erlang should return ["James", "Legible", "Hey", "Think"]
This is the code I have so far:
-module(testmodule).
-export([NameInFront/1]).
NameInFront(List)-> ["James"]++[List].
It works just fine when I type in just one word, which I guess it the fault of the NameInFront/1 part but I want it to be able to handle any amount of words I type in. Anyone know how I can get my function to handle multiple inputs? Thank you very much.
I'm not quite sure what you mean: whether you want your function to be variadic (take a flexible number of arguments), or you are having trouble getting your lists to join together properly.
Variadic functions are not the way Erlang works. FunctionName/Arity defines the concrete identity of a function in Erlang (discussed here). So our way of having a function take multiple arguments is to make one (or more) of the arguments a list:
print_terms(Terms) -> io:format("~tp~n", [Terms]).
The io:format/2 function itself actually takes a list as its second function, which is how it deals with a variable number of arguments:
print_two_things(ThingOne, ThingTwo) ->
io:format("~tp~n~tp~n", [ThingOne, ThingTwo]).
In your case you want to accept a list of things, add your name to it, and print it out. This is one way to do it.
name_in_front(ListOfStrings) ->
NewList = ["James" | ListOfStrings],
io:format("~p~n", [NewList]).
Using the ++ operator is another (which is actually a different syntax for a recursive operation which expands to the exact same thing, ):
name_in_front(ListOfStrings) ->
NewList = ["James"] ++ ListOfStrings,
io:format("~tp~n", [NewList]).
But that's a little silly, because it is intended to join two strings together in a simple way, and in this case it makes the syntax look weird.
Yet another way would be to more simply write a function that take two arguments and accomplishes the same thing:
any_name_in_front(Name, ListOfThings) ->
io:format("~tp~n", [[Name | ListOfThings]]).
The double [[]] is because io:format/2 takes a list as its second argument, and you want to pass a list of one thing (itself a list) into a single format substitution slot (the "~tp" part).
One thing to note is that capitalization matters in Erlang. It has a meaning. Module and function names are atoms, which are not the same thing as variables. For this reason they must be lowercase, and because they must be lowercase to start with the convention is to use underscores between words instead of usingCamelCase. Because, well, erlangIsNotCpp.
Play around in the shell a bit with the simple elements of the function you want, and once you have them ironed out write it into a source file and give it a try.

Building lists of data types in Haskell

I'm really confused about how your supposed to get data out of typeclasses in haskell. I'm coming for a C background so finding it really difficult that you can't just access the data. What I have is something like this:
data MyType = MyType String deriving (Show)
display :: [MyType] -> IO ()
display ((MyType name):xs) = do
display xs
putStr name
Basically here I want to access 'name' however it just doesn't seem to work. Can I access the data within an instance of a typeclass by just having a reference to the object in my code or do I have to map its contents to variables? and if so how?
Links to good tutorials on this would be appreciated, I've read 'Learn you a Haskell for great good' but when I try to deviate from the examples given there always seems to be to much I need to know to get it done.
-A
I think you might just be missing some little pieces that tie it all together.
Firstly, you have a perfectly fine data type, MyType, that holds strings:
data MyType = MyType String deriving (Show)
Now, you want to write a function that walks a list of such type, printing each element as it goes. We do this via recursion over the list data type.
Since lists have two cases, the empty list, [], and the cons case, (:), we have two branches:
display :: [MyType] -> IO ()
display [] = return ()
display ((MyType name):xs) = do
putStrLn name
display xs
Now, where I think you might have go stuck was building some data of this type. You already know how to take it apart with pattern matching, and you build the data using almost the same syntax. Here's a list of MyType:
table =
[ MyType "john"
, MyType "don"
, MyType "eric"
, MyType "trevor"
]
Finally, you can run your program from main
main = display table
Note, there's no typeclasses here, just algebraic data types (introduced with data).
First of all, I am a bit confused about the words you use. A typeclass is a way to overload functions. What you have is an algebraic data type. The problem you have (if I understood it correctly) is well known. For the purpose of accessing data easier, you could use record syntax:
data Foo = Foo {
bar :: Int
, baz :: String
}
Do you see the similarity to a struct in C? Using record syntax, some interesting things are possible:
bar y -- access member bar of y
y { bar = z } -- Make a new record but with field bar changed to the value of z
and some other thing too.