Is there any way to print a module type without using a function in that module? - io

Let's say I have a module like this:
module type MyModule =
sig
type t
func1 : ... -> t
end
(* Implementation *)
module SomeModule : MyModule =
struct
type t = int
let func1 ... : t =
(* do something and return type t *)
end
Now, I called func1 somewhere outside the module and obtained a value with type MyModule.t:
let x = SomeModule.func1 ... in
print_int x (* Which doesn't works *)
So I'm wondering is there any way to print x?
Thanks for answering!

The short answer is "no". You've specifically made the type t abstract, so there is no way to do anything with values of type t outside SomeModule.
There are of course sneaky ways to subvert the type system in OCaml (as in every language), but generally speaking you should avoid them like the plague.

Related

Haskell type constructor in generic function

I'm digging around in the Haskell Lava HDL system and am stuck in
understanding
http://hackage.haskell.org/package/chalmers-lava2000-1.6.1/docs/src/Lava-Vhdl.html#writeVhdl
Can someone tell me what function (var "inp") in writeVhdlresolves to?
Function var is not defined yet and seems to be generated with some meta-programming that is not familiar to me in class Constructive in http://hackage.haskell.org/package/chalmers-lava2000-1.6.1/docs/src/Lava-Generic.html#line-253 .
Function var seems to act like a constructor. How is this mechanism working?
The input to writeVhdl is a circuit description like
halfAdd (a, b) = (sum, arry)
where
sum = xor2 (a, b)
arry = and2 (a, b)
Can someone tell me what function (var "inp") in writeVhdlresolves to?
It depends on what you pass to writeVhdl 2nd argument, namely circ. The type of its argument (if I read that correctly) is exactly the type that gets returned by var "foo".
You can observe expression types in ghci by typing :t some expression. Try loading your code into GHCi session and play with :t command.

Haskell type declaration using arrow operator

I encountered a Haskell type declaration using arrow operator like the following :
type Acceleration = State -> Vec
But how can that be ? coz I've never encountered such use before (in learning Haskell tutorials).
if the declaration is a-OK then what its definition should look like ?
How do I even use such a type ?
That's a type synonym. It's expressing that an Acceleration is a function that goes from State to Vec.
Simplify a bit and imagine the set of functions that go from Int to String. Let's call them Frobnicators.
type Frobnicator = Int -> String
We can define such a function which we could then say has a type of Frobnicator.
foo :: Frobnicator
foo = show . (+3)

Why does OCaml sometimes require eta expansion?

If I have the following OCaml function:
let myFun = CCVector.map ((+) 1);;
It works fine in Utop, and Merlin doesn't mark it as a compilation error. When I try to compile it, however, I get the following error:
Error: The type of this expression,
(int, '_a) CCVector.t -> (int, '_b) CCVector.t,
contains type variables that cannot be generalized
If I eta-expand it however then it compiles fine:
let myFun foo = CCVector.map ((+) 1) foo;;
So I was wondering why it doesn't compile in eta-reduced form, and also why the eta-reduced form seems to work in the toplevel (Utop) but not when compiling?
Oh, and the documentation for CCVector is here. The '_a part can be either `RO or `RW, depending whether it is read-only or mutable.
What you got here is the value polymorphism restriction of ML language family.
The aim of the restriction is to settle down let-polymorphism and side effects together. For example, in the following definition:
let r = ref None
r cannot have a polymorphic type 'a option ref. Otherwise:
let () =
r := Some 1; (* use r as int option ref *)
match !r with
| Some s -> print_string s (* this time, use r as a different type, string option ref *)
| None -> ()
is wrongly type-checked as valid, but it crashes, since the reference cell r is used for these two incompatible types.
To fix this issue many researches were done in 80's, and the value polymoprhism is one of them. It restricts polymorphism only to let bindings whose definition form is "non-expansive". Eta expanded form is non expansive therefore your eta expanded version of myFun has a polymorphic type, but not for eta reduced one. (More precisely speaking, OCaml uses a relaxed version of this value polymorphism, but the story is basically the same.)
When the definition of let binding is expansive there is no polymorphism introduced therefore the type variables are left non-generalized. These types are printed as '_a in the toplevel, and their intuitive meaning is: they must be instantiated to some concrete type later:
# let r = ref None (* expansive *)
val r : '_a option ref = {contents = None} (* no polymorphism is allowed *)
(* type checker does not reject this,
hoping '_a is instantiated later. *)
We can fix the type '_a after the definition:
# r := Some 1;; (* fixing '_a to int *)
- : unit = ()
# r;;
- : int option ref = {contents = Some 1} (* Now '_a is unified with int *)
Once fixed, you cannot change the type, which prevents the crash above.
This typing delay is permitted until the end of the typing of the compilation unit. The toplevel is a unit which never ends and therefore you can have values with '_a type variables anywhere of the session. But in the separated compilation, '_a variables must be instantiated to some type without type variables till the end of ml file:
(* test.ml *)
let r = ref None (* r : '_a option ref *)
(* end of test.ml. Typing fails due to the non generalizable type variable remains. *)
This is what is happening with your myFun function with the compiler.
AFAIK, there is no perfect solution to the problem of polymorphism and side effects. Like other solutions, the value polymorphism restriction has its own drawback: if you want to have a polymorphic value, you must make the definition in non-expansive: you must eta-expand myFun. This is a bit lousy but is considered acceptable.
You can read some other answers:
http://caml.inria.fr/pub/old_caml_site/FAQ/FAQ_EXPERT-eng.html#variables_de_types_faibles
What is the difference between 'a and '_l?
or search by like "value restriction ml"

learning type of argument in function

How can I learn type of argument at function in Haskell ? In python, we have type ( ) function.
Ex:
in func;
if type ( a ) == Int
do <something>
But, I don't know how I can manage that wish in Haskell ?
You don't need this since Haskell is statically typed and all types are known at compile time. In case of polymorphic functions like length :: [a] -> Int (Calculate the length of a list of elements of type a), there is no way to find out about the type of the argument, since you specified with the type that any argument type fits.
You have http://hackage.haskell.org/packages/archive/base/latest/doc/html/Data-Typeable.html
However compared to dynamic languages it is very very rare that you need to use such means, and as beginner you shouldn't even try to use it, as you're almost certainly doing it wrong, even if you are sure that you need it. You should embrace Haskell's battle cry "Follow the type!" and express your thoughts using the type system instead of trying to subvert it.
If you are trying to do type-directed dispatch, then you probably want a typeclass.
data Bar = ...
class Foo a where
foo :: a -> Bar
instance Foo Int where
foo = ...
func :: Foo a => a -> ...
func x ... = ... foo x ...
Notice how the type signature demands that x is an instance of the Foo class. That means we can call foo on x and the type-directed dispatch will be done for us, in a type-safe way. If you write code that tries to call foo on something that is not an instance of Foo, then it will be a type error.
The reason you are not allowed to perform your own type-directed dispatch in Haskell is because that would break some important guarantees given to you by the type system. We would have to say goodbye to our theorems for free.

SML conversions to Haskell

A few basic questions, for converting SML code to Haskell.
1) I am used to having local embedded expressions in SML code, for example test expressions, prints, etc. which functions local tests and output when the code is loaded (evaluated).
In Haskell it seems that the only way to get results (evaluation) is to add code in a module, and then go to main in another module and add something to invoke and print results.
Is this right? in GHCi I can type expressions and see the results, but can this be automated?
Having to go to the top level main for each test evaluation seems inconvenient to me - maybe just need to shift my paradigm for laziness.
2) in SML I can do pattern matching and unification on a returned result, e.g.
val myTag(x) = somefunct(a,b,c);
and get the value of x after a match.
Can I do something similar in Haskell easily, without writing separate extraction functions?
3) How do I do a constructor with a tuple argument, i.e. uncurried.
in SML:
datatype Thing = Info of Int * Int;
but in Haskell, I tried;
data Thing = Info ( Int Int)
which fails. ("Int is applied to too many arguments in the type:A few Int Int")
The curried version works fine,
data Thing = Info Int Int
but I wanted un-curried.
Thanks.
This question is a bit unclear -- you're asking how to evaluate functions in Haskell?
If it is about inserting debug and tracing into pure code, this is typically only needed for debugging. To do this in Haskell, you can use Debug.Trace.trace, in the base package.
If you're concerned about calling functions, Haskell programs evaluate from main downwards, in dependency order. In GHCi you can, however, import modules and call any top-level function you wish.
You can return the original argument to a function, if you wish, by making it part of the function's result, e.g. with a tuple:
f x = (x, y)
where y = g a b c
Or do you mean to return either one value or another? Then using a tagged union (sum-type), such as Either:
f x = if x > 0 then Left x
else Right (g a b c)
How do I do a constructor with a tuple argument, i.e. uncurried in SML
Using the (,) constructor. E.g.
data T = T (Int, Int)
though more Haskell-like would be:
data T = T Int Bool
and those should probably be strict fields in practice:
data T = T !Int !Bool
Debug.Trace allows you to print debug messages inline. However, since these functions use unsafePerformIO, they might behave in unexpected ways compared to a call-by-value language like SML.
I think the # syntax is what you're looking for here:
data MyTag = MyTag Int Bool String
someFunct :: MyTag -> (MyTag, Int, Bool, String)
someFunct x#(MyTag a b c) = (x, a, b, c) -- x is bound to the entire argument
In Haskell, tuple types are separated by commas, e.g., (t1, t2), so what you want is:
data Thing = Info (Int, Int)
Reading the other answers, I think I can provide a few more example and one recommendation.
data ThreeConstructors = MyTag Int | YourTag (String,Double) | HerTag [Bool]
someFunct :: Char -> Char -> Char -> ThreeConstructors
MyTag x = someFunct 'a' 'b' 'c'
This is like the "let MyTag x = someFunct a b c" examples, but it is a the top level of the module.
As you have noticed, Haskell's top level can defined commands but there is no way to automatically run any code merely because your module has been imported by another module. This is entirely different from Scheme or SML. In Scheme the file is interpreted as being executed form-by-form, but Haskell's top level is only declarations. Thus Libraries cannot do normal things like run initialization code when loaded, they have to provide a "pleaseRunMe :: IO ()" kind of command to do any initialization.
As you point out this means running all the tests requires some boilerplate code to list them all. You can look under hackage's Testing group for libraries to help, such as test-framework-th.
For #2, yes, Haskell's pattern matching does the same thing. Both let and where do pattern matching. You can do
let MyTag x = someFunct a b c
in ...
or
...
where MyTag x = someFunct a b c

Resources