F# using inline: still fail to match different type for generic function - function

I tried to use "inline" to define a function that would fit into different input parameter types:
> let x=2.0
- let inline f x=x+1
- f x;;
f x;;
--^
stdin(6,3): error FS0001: This expression was expected to have type
int
but here has type
float
I expect that after applying "inline" on f, I got a generic function call "f". but seems failed.
How to correct it?

The best way is to use genericOne like so:
let inline f x = x + LanguagePrimitives.GenericOne
This is because when you have used 1, the compiler has infered that the function argument must be an int as you can only add ints to other ints
then you can call it with
> f 1;;
val it : int = 2
> f 1.0;;
val it : float = 2.0

That's because you're adding 1 in your function. Because of that x has to be an int.
inline would work if you provide both sides of + as parameters:
> let inline f x y = x + y;;
val inline f :
x: ^a -> y: ^b -> ^c
when ( ^a or ^b) : (static member ( + ) : ^a * ^b -> ^c)
As you can see, it's type is resolved as any type with +. You can use it to add two intsor twofloat`s together:
> f 1 2;;
val it : int = 3
> f 1. 2.;;
val it : float = 3.0
You can't however use it to add an int to a float:
> f 1. 2;;
f 1. 2;;
-----^
stdin(9,6): error FS0001: The type 'int' does not match the type 'float'

Related

How can I return a lambda with guards and double recursion?

I made this function in Python:
def calc(a): return lambda op: {
'+': lambda b: calc(a+b),
'-': lambda b: calc(a-b),
'=': a}[op]
So you can make a calculation like this:
calc(1)("+")(1)("+")(10)("-")(7)("=")
And the result will be 5.
I wanbt to make the same function in Haskell to learn about lambdas, but I am getting parse errors.
My code looks like this:
calc :: Int -> (String -> Int)
calc a = \ op
| op == "+" = \ b calc a+b
| op == "-" = \ b calc a+b
| op == "=" = a
main = calc 1 "+" 1 "+" 10 "-" 7 "="
There are numerous syntactical problems with the code you have posted. I won't address them here, though: you will discover them yourself after going through a basic Haskell tutorial. Instead I'll focus on a more fundamental problem with the project, which is that the types don't really work out. Then I'll show a different approach that gets you the same outcome, to show you it is possible in Haskell once you've learned more.
While it's fine in Python to sometimes return a function-of-int and sometimes an int, this isn't allowed in Haskell. GHC has to know at compile time what type will be returned; you can't make that decision at runtime based on whether a string is "=" or not. So you need a different type for the "keep calcing" argument than the "give me the answer" argument.
This is possible in Haskell, and in fact is a technique with a lot of applications, but it's maybe not the best place for a beginner to start. You are inventing continuations. You want calc 1 plus 1 plus 10 minus 7 equals to produce 5, for some definitions of the names used therein. Achieving this requires some advanced features of the Haskell language and some funny types1, which is why I say it is not for beginners. But, below is an implementation that meets this goal. I won't explain it in detail, because there is too much for you to learn first. Hopefully after some study of Haskell fundamentals, you can return to this interesting problem and understand my solution.
calc :: a -> (a -> r) -> r
calc x k = k x
equals :: a -> a
equals = id
lift2 :: (a -> a -> a) -> a -> a -> (a -> r) -> r
lift2 f x y = calc (f x y)
plus :: Num a => a -> a -> (a -> r) -> r
plus = lift2 (+)
minus :: Num a => a -> a -> (a -> r) -> r
minus = lift2 (-)
ghci> calc 1 plus 1 plus 10 minus 7 equals
5
1 Of course calc 1 plus 1 plus 10 minus 7 equals looks a lot like 1 + 1 + 10 - 7, which is trivially easy. The important difference here is that these are infix operators, so this is parsed as (((1 + 1) + 10) - 7), while the version you're trying to implement in Python, and my Haskell solution, are parsed like ((((((((calc 1) plus) 1) plus) 10) minus) 7) equals) - no sneaky infix operators, and calc is in control of all combinations.
chi's answer says you could do this with "convoluted type class machinery", like printf does. Here's how you'd do that:
{-# LANGUAGE ExtendedDefaultRules #-}
class CalcType r where
calc :: Integer -> String -> r
instance CalcType r => CalcType (Integer -> String -> r) where
calc a op
| op == "+" = \ b -> calc (a+b)
| op == "-" = \ b -> calc (a-b)
instance CalcType Integer where
calc a op
| op == "=" = a
result :: Integer
result = calc 1 "+" 1 "+" 10 "-" 7 "="
main :: IO ()
main = print result
If you wanted to make it safer, you could get rid of the partiality with Maybe or Either, like this:
{-# LANGUAGE ExtendedDefaultRules #-}
class CalcType r where
calcImpl :: Either String Integer -> String -> r
instance CalcType r => CalcType (Integer -> String -> r) where
calcImpl a op
| op == "+" = \ b -> calcImpl (fmap (+ b) a)
| op == "-" = \ b -> calcImpl (fmap (subtract b) a)
| otherwise = \ b -> calcImpl (Left ("Invalid intermediate operator " ++ op))
instance CalcType (Either String Integer) where
calcImpl a op
| op == "=" = a
| otherwise = Left ("Invalid final operator " ++ op)
calc :: CalcType r => Integer -> String -> r
calc = calcImpl . Right
result :: Either String Integer
result = calc 1 "+" 1 "+" 10 "-" 7 "="
main :: IO ()
main = print result
This is rather fragile and very much not recommended for production use, but there it is anyway just as something to (eventually?) learn from.
Here is a simple solution that I'd say corresponds more closely to your Python code than the advanced solutions in the other answers. It's not an idiomatic solution because, just like your Python one, it will use runtime failure instead of types in the compiler.
So, the essence in you Python is this: you return either a function or an int. In Haskell it's not possible to return different types depending on runtime values, however it is possible to return a type that can contain different data, including functions.
data CalcResult = ContinCalc (Int -> String -> CalcResult)
| FinalResult Int
calc :: Int -> String -> CalcResult
calc a "+" = ContinCalc $ \b -> calc (a+b)
calc a "-" = ContinCalc $ \b -> calc (a-b)
calc a "=" = FinalResult a
For reasons that will become clear at the end, I would actually propose the following variant, which is, unlike typical Haskell, not curried:
calc :: (Int, String) -> CalcResult
calc (a,"+") = ContinCalc $ \b op -> calc (a+b,op)
calc (a,"-") = ContinCalc $ \b op -> calc (a-b,op)
calc (a,"=") = FinalResult a
Now, you can't just pile on function applications on this, because the result is never just a function – it can only be a wrapped function. Because applying more arguments than there are functions to handle them seems to be a failure case, the result should be in the Maybe monad.
contin :: CalcResult -> (Int, String) -> Maybe CalcResult
contin (ContinCalc f) (i,op) = Just $ f i op
contin (FinalResult _) _ = Nothing
For printing a final result, let's define
printCalcRes :: Maybe CalcResult -> IO ()
printCalcRes (Just (FinalResult r)) = print r
printCalcRes (Just _) = fail "Calculation incomplete"
printCalcRes Nothing = fail "Applied too many arguments"
And now we can do
ghci> printCalcRes $ contin (calc (1,"+")) (2,"=")
3
Ok, but that would become very awkward for longer computations. Note that we have after two operations a Maybe CalcResult so we can't just use contin again. Also, the parentheses that would need to be matched outwards are a pain.
Fortunately, Haskell is not Lisp and supports infix operators. And because we're anyways getting Maybe in the result, might as well include the failure case in the data type.
Then, the full solution is this:
data CalcResult = ContinCalc ((Int,String) -> CalcResult)
| FinalResult Int
| TooManyArguments
calc :: (Int, String) -> CalcResult
calc (a,"+") = ContinCalc $ \(b,op) -> calc (a+b,op)
calc (a,"-") = ContinCalc $ \(b,op) -> calc (a-b,op)
calc (a,"=") = FinalResult a
infixl 9 #
(#) :: CalcResult -> (Int, String) -> CalcResult
ContinCalc f # args = f args
_ # _ = TooManyArguments
printCalcRes :: CalcResult -> IO ()
printCalcRes (FinalResult r) = print r
printCalcRes (ContinCalc _) = fail "Calculation incomplete"
printCalcRes TooManyArguments = fail "Applied too many arguments"
Which allows to you write
ghci> printCalcRes $ calc (1,"+") # (2,"+") # (3,"-") # (4,"=")
2
A Haskell function of type A -> B has to return a value of the fixed type B every time it's called (or fail to terminate, or throw an exception, but let's neglect that).
A Python function is not similarly constrained. The returned value can be anything, with no type constraints. As a simple example, consider:
def foo(b):
if b:
return 42 # int
else:
return "hello" # str
In the Python code you posted, you exploit this feature to make calc(a)(op) to be either a function (a lambda) or an integer.
In Haskell we can't do that. This is to ensure that the code can be type checked at compile-time. If we write
bar :: String -> Int
bar s = foo (reverse (reverse s) == s)
the compiler can't be expected to verify that the argument always evaluates to True -- that would be undecidable, in general. The compiler merely requires that the type of foo is something like Bool -> Int. However, we can't assign that type to the definition of foo shown above.
So, what we can actually do in Haskell?
One option could be to abuse type classes. There is a way in Haskell to create a kind of "variadic" function exploiting some kind-of convoluted type class machinery. That would make
calc 1 "+" 1 "+" 10 "-" 7 :: Int
type-check and evaluate to the wanted result. I'm not attempting that: it's complex and "hackish", at least in my eye. This hack was used to implement printf in Haskell, and it's not pretty to read.
Another option is to create a custom data type and add some infix operator to the calling syntax. This also exploits some advanced feature of Haskell to make everything type check.
{-# LANGUAGE GADTs, FunctionalDependencies, TypeFamilies, FlexibleInstances #-}
data R t where
I :: Int -> R String
F :: (Int -> Int) -> R Int
instance Show (R String) where
show (I i) = show i
type family Other a where
Other String = Int
Other Int = String
(#) :: R a -> a -> R (Other a)
I i # "+" = F (i+) -- equivalent to F (\x -> i + x)
I i # "-" = F (i-) -- equivalent to F (\x -> i - x)
F f # i = I (f i)
I _ # s = error $ "unsupported operator " ++ s
main :: IO ()
main =
print (I 1 # "+" # 1 # "+" # 10 # "-" # 7)
The last line prints 5 as expected.
The key ideas are:
The type R a represents an intermediate result, which can be an integer or a function. If it's an integer, we remember that the next thing in the line should be a string by making I i :: R String. If it's a function, we remember the next thing should be an integer by having F (\x -> ...) :: R Int.
The operator (#) takes an intermediate result of type R a, a next "thing" (int or string) to process of type a, and produces a value in the "other type" Other a. Here, Other a is defined as the type Int (respectively String) when a is String (resp. Int).

Representing Higher-Order Functors as Containers in Coq

Following this approach, I'm trying to model functional programs using effect handlers in Coq, based on an implementation in Haskell. There are two approaches presented in the paper:
Effect syntax is represented as a functor and combined with the free monad.
data Prog sig a = Return a | Op (sig (Prog sig a))
Due to the termination check not liking non-strictly positive definitions, this data type can't be defined directly. However, containers can be used to represent strictly-positive functors, as described in this paper. This approach works but since I need to model a scoped effect that requires explicit scoping syntax, mismatched begin/end tags are possible. For reasoning about programs, this is not ideal.
The second approach uses higher-order functors, i.e. the following data type.
data Prog sig a = Return a | Op (sig (Prog sig) a)
Now sig has the type (* -> *) -> * -> *. The data type can't be defined in Coq for the same reasons as before. I'm looking for ways to model this data type, so that I can implement scoped effects without explicit scoping tags.
My attempts of defining a container for higher-order functors have not been fruitful and I can't find anything about this topic. I'm thankful for pointers in the right direction and helpful comments.
Edit: One example of scoped syntax from the paper that I would like to represent is the following data type for exceptions.
data HExc e m a = Throw′ e | forall x. Catch′ (m x) (e -> m x) (x -> m a)
Edit2: I have merged the suggested idea with my approach.
Inductive Ext Shape (Pos : Shape -> Type -> Type -> Type) (F : Type -> Type) A :=
ext : forall s, (forall X, Pos s A X -> F X) -> Ext Shape Pos F A.
Class HContainer (H : (Type -> Type) -> Type -> Type):=
{
Shape : Type;
Pos : Shape -> Type -> Type -> Type;
to : forall M A, Ext Shape Pos M A -> H M A;
from : forall M A, H M A -> Ext Shape Pos M A;
to_from : forall M A (fx : H M A), #to M A (#from M A fx) = fx;
from_to : forall M A (e : Ext Shape Pos M A), #from M A (#to M A e) = e
}.
Section Free.
Variable H : (Type -> Type) -> Type -> Type.
Inductive Free (HC__F : HContainer H) A :=
| pure : A -> Free HC__F A
| impure : Ext Shape Pos (Free HC__F) A -> Free HC__F A.
End Free.
The code can be found here. The Lambda Calculus example works and I can prove that the container representation is isomorphic to the data type.
I have tried to to the same for a simplified version of the exception handler data type but it does not fit the container representation.
Defining a smart constructor does not work, either. In Haskell, the constructor works by applying Catch' to a program where an exception may occur and a continuation, which is empty in the beginning.
catch :: (HExc <: sig) => Prog sig a -> Prog sig a
catch p = inject (Catch' p return)
The main issue I see in the Coq implementation is that the shape needs to be parameterized over a functor, which leads to all sorts of problems.
This answer gives more intuition about how to derive containers from functors than my previous one. I'm taking quite a different angle, so I'm making a new answer instead of revising the old one.
Simple recursive types
Let's consider a simple recursive type first to understand non-parametric containers, and for comparison with the parameterized generalization. Lambda calculus, without caring about scopes, is given by the following functor:
Inductive LC_F (t : Type) : Type :=
| App : t -> t -> LC_F t
| Lam : t -> LC_F t
.
There are two pieces of information we can learn from this type:
The shape tells us about the constructors (App, Lam), and potentially also auxiliary data not relevant to the recursive nature of the syntax (none here). There are two constructors, so the shape has two values. Shape := App_S | Lam_S (bool also works, but declaring shapes as standalone inductive types is cheap, and named constructors also double as documentation.)
For every shape (i.e., constructor), the position tells us about recursive occurences of syntax in that constructor. App contains two subterms, hence we can define their two positions as booleans; Lam contains one subterm, hence its position is a unit. One could also make Pos (s : Shape) an indexed inductive type, but that is a pain to program with (just try).
(* Lambda calculus *)
Inductive ShapeLC :=
| App_S (* The shape App _ _ *)
| Lam_S (* The shape Lam _ *)
.
Definition PosLC s :=
match s with
| App_S => bool
| Lam_S => unit
end.
Parameterized recursive types
Now, properly scoped lambda calculus:
Inductive LC_F (f : Type -> Type) (a : Type) : Type :=
| App : f a -> f a -> LC_F a
| Lam : f (unit + a) -> LC_F a
.
In this case, we can still reuse the Shape and Pos data from before. But this functor encodes one more piece of information: how each position changes the type parameter a. I call this parameter the context (Ctx).
Definition CtxLC (s : ShapeLC) : PosLC s -> Type -> Type :=
match s with
| App_S => fun _ a => a (* subterms of App reuse the same context *)
| Lam_S => fun _ a => unit + a (* Lam introduces one variable in the context of its subterm *)
end.
This container (ShapeLC, PosLC, CtxLC) is related to the functor LC_F by an isomorphism: between the sigma { s : ShapeLC & forall p : PosLC s, f (CtxLC s p a) } and LC_F a. In particular, note how the function y : forall p, f (CtxLC s p) tells you exactly how to fill the shape s = App_S or s = Lam_S to construct a value App (y true) (y false) : LC_F a or Lam (y tt) : LC_F a.
My previous representation encoded Ctx in some additional type indices of Pos. The representations are equivalent, but this one here looks tidier.
Exception handler calculus
We'll consider just the Catch constructor. It has four fields: a type X, the main computation (which returns an X), an exception handler (which also recovers an X), and a continuation (consuming the X).
Inductive Exc_F (E : Type) (F : Type -> Type) (A : Type) :=
| ccatch : forall X, F X -> (E -> F X) -> (X -> F A) -> Exc_F E F A.
The shape is a single constructor, but you must include X. Essentially, look at all the fields (possibly unfolding nested inductive types), and keep all the data that doesn't mention F, that's your shape.
Inductive ShapeExc :=
| ccatch_S (X : Type) (* The shape ccatch X _ (fun e => _) (fun x => _) *)
.
(* equivalently, Definition ShapeExc := Type. *)
The position type lists all the ways to get an F out of an Exc_F of the corresponding shape. In particular, a position contains the arguments to apply functions with, and possibly any data to resolve branching of any other sort. In particular, you need to know the exception type to store exceptions for the handler.
Inductive PosExc (E : Type) (s : ShapeExc) : Type :=
| main_pos (* F X *)
| handle_pos (e : E) (* E -> F X *)
| continue_pos (x : getX s) (* X -> F A *)
.
(* The function getX takes the type X contained in a ShapeExc value, by pattern-matching: getX (ccatch_S X) := X. *)
Finally, for each position, you need to decide how the context changes, i.e., whether you're now computing an X or an A:
Definition Ctx (E : Type) (s : ShapeExc) (p : PosExc E s) : Type -> Type :=
match p with
| main_pos | handle_pos _ => fun _ => getX s
| continue_pos _ => fun A => A
end.
Using the conventions from your code, you can then encode the Catch constructor as follows:
Definition Catch' {E X A}
(m : Free (C__Exc E) X)
(h : E -> Free (C__Exc E) X)
(k : X -> Free (C__Exc E) A) : Free (C__Exc E) A :=
impure (#ext (C__Exc E) (Free (C__Exc E)) A (ccatch_S X) (fun p =>
match p with
| main_pos => m
| handle_pos e => h e
| continue_pos x => k x
end)).
(* I had problems with type inference for some reason, hence #ext is explicitly applied *)
Full gist https://gist.github.com/Lysxia/6e7fb880c14207eda5fc6a5c06ef3522
The main trick in the "first-order" free monad encoding is to encode a functor F : Type -> Type as a container, which is essentially a dependent pair { Shape : Type ; Pos : Shape -> Type }, so that, for all a, the type F a is isomorphic to the sigma type { s : Shape & Pos s -> a }.
Taking this idea further, we can encode a higher-order functor F : (Type -> Type) -> (Type -> Type) as a container { Shape : Type & Pos : Shape -> Type -> (Type -> Type) }, so that, for all f and a, F f a is isomorphic to { s : Shape & forall x : Type, Pos s a x -> f x }.
I don't quite understand what the extra Type parameter in Pos is doing there, but It Works™, at least to the point that you can construct some lambda calculus terms in the resulting type.
For example, the lambda calculus syntax functor:
Inductive LC_F (f : Type -> Type) (a : Type) : Type :=
| App : f a -> f a -> LC_F a
| Lam : f (unit + a) -> LC_F a
.
is represented by the container (Shape, Pos) defined as:
(* LC container *)
Shape : Type := bool; (* Two values in bool = two constructors in LC_F *)
Pos (b : bool) : Type -> (Type -> Type) :=
match b with
| true => App_F
| false => Lam_F
end;
where App_F and Lam_F are given by:
Inductive App_F (a : Type) : TyCon :=
| App_ (b : bool) : App_F a a
.
Inductive Lam_F (a : Type) : TyCon :=
| Lam_ : Lam_F a (unit + a)
.
Then the free-like monad Prog (implicitly parameterized by (Shape, Pos)) is given by:
Inductive Prog (a : Type) : Type :=
| Ret : a -> Prog a
| Op (s : Shape) : (forall b, Pos s a b -> Prog b) -> Prog a
.
Having defined some boilerplate, you can write the following example:
(* \f x -> f x x *)
Definition omega {a} : LC a :=
Lam (* f *) (Lam (* x *)
(let f := Ret (inr (inl tt)) in
let x := Ret (inl tt) in
App (App f x) x)).
Full gist: https://gist.github.com/Lysxia/5485709c4594b836113736626070f488

F# generics / function overloading syntax

I'm confused on how to label a function as generic without an explicit type declaration like ('a -> 'a)
let add a b = a + b
This gives us
val add : a:int -> b:int -> int
However we can then immediately call
add "Hello " "World!"
and now the value of add is
val add : a:string -> b:string -> string
val it : string = "Hello World!"
If we then call
add 2 3 // then we get
error: This expression was expected to have type string but here has type int
How do I ensure that a function works on all types that say have the function (+) defined
This is F#'s embarrassing skeleton in the closet.
Try this:
> let mapPair f (x,y) = (f x, f y)
val mapPair : f:('a -> 'b) -> x:'a * y:'a -> 'b * 'b
Fully generic! Clearly, function application and tuples work.
Now try this:
> let makeList a b = [a;b]
val makeList : a:'a -> b:'a -> 'a list
Hmmm, also generic. How about this:
> let makeList a b = [a + b]
val makeList : a:int -> b:int -> int list
Aha, as soon as I have a (+) in there, it becomes int for some reason.
Let's keep playing:
> let inline makeList a b = [a + b]
val inline makeList :
a: ^a -> b: ^b -> ^c list
when ( ^a or ^b) : (static member ( + ) : ^a * ^b -> ^c)
Hmmm, interesting. Turns out, if I make the function inline, then F# does consider it generic, but it also gives it this weird when clause, and my generic parameters have this strange ^ symbol instead of the usual tick.
This strange syntax is called "statically resolved type parameters" (see here for a somewhat coherent explanation), and the basic idea is that the function (+) requires its arguments to have a static member (+) defined. Let's verify:
> let x = 0 :> obj
let y = 0 :> obj
let z = x + y
Script1.fsx(14,13): error FS0001: The type 'obj' does not support the operator '+'
> type My() =
static member (+)( a:My, b:My ) = My()
let x = My()
let y = My()
let z = x + y
val x : My
val y : My
val z : My
Now, the problem with this is that CLR does not support this kind of generic parameters (i.e. "any type, as long as it has such and such members"), so F# has to fake it and resolve these calls at compile time. But because of this, any methods that use this feature cannot be compiled to true generic IL methods, and thus have to be monomorphised (which is enabled by inline).
But then, it would be very inconvenient to require that every function that uses arithmetic operators be declared inline, wouldn't it? So F# goes yet another extra step and tries to fix these statically resolved generic parameters based on how they are instantiated later in the code. That's why your function turns into string->string->string as soon as you use it with a string once.
But if you mark your function inline, F# wouldn't have to fix parameters, because it wouldn't have to compile the function down to IL, and so your parameters remain intact:
> let inline add a b = a + b
val inline add :
a: ^a -> b: ^b -> ^c
when ( ^a or ^b) : (static member ( + ) : ^a * ^b -> ^c)
If I understand you correctly, use inline:
let inline add a b = a + b
add 2 3 |> printfn "%A"
add "Hello " "World!" |> printfn "%A"
Print:
5
"Hello World!"
Link: http://ideone.com/awsYNI
Make it inline
let inline add a b = a + b
(*
val inline add :
a: ^a -> b: ^b -> ^c
when ( ^a or ^b) : (static member ( + ) : ^a * ^b -> ^c)
*)
add "Hello " "World!"
// val it : string = "Hello World!"
add 2 3
// val it : int = 5

Int and Num type of haskell

I have below code to take the args to set some offset time.
setOffsetTime :: (Ord a, Num b)=>[a] -> b
setOffsetTime [] = 200
setOffsetTime (x:xs) = read x::Int
But compiler says "Could not deduce (b ~ Int) from the context (Ord a, Num b) bound by the type signature for setOffsetTime :: (Ord a, Num b) => [a] -> b
Also I found I could not use 200.0 if I want float as the default value. The compilers says "Could not deduce (Fractional b) arising from the literal `200.0'"
Could any one show me some code as a function (not in the prelude) that takes an arg to store some variable so I can use in other function? I can do this in the main = do, but hope
to use an elegant function to achieve this.
Is there any global constant stuff in Hasekll? I googled it, but seems not.
I wanna use Haskell to replace some of my python script although it is not easy.
I think this type signature doesn't quite mean what you think it does:
setOffsetTime :: (Ord a, Num b)=>[a] -> b
What that says is "if you give me a value of type [a], for any type a you choose that is a member of the Ord type class, I will give you a value of type b, for any type b that you choose that is a member of the Num type class". The caller gets to pick the particular types a and b that are used each time setOffsetTime is called.
So trying to return a value of type Int (or Float, or any particular type) doesn't make sense. Int is indeed a member of the type class Num, but it's not any member of the type class Num. According to that type signature, I should be able to make a brand new instance of Num that you've never seen before, import setOffsetTime from your module, and call it to get a value of my new type.
To come up with an acceptable return value, you can only use functions that likewise return an arbitrary Num. You can't use any functions of particular concrete types.
Existential types are essentially a mechanism for allowing the callee to choose the value for a type variable (and then the caller has to be written to work regardless of what that type is), but that's not really something you want to be getting into while you're still learning.
If you are convinced that the implementation of your function is correct, i.e., that it should interpret the first element in its input list as the number to return and return 200 if there is no such argument, then you only need to make sure that the type signature matches that implementation (which it does not do, right now).
To do so, you could, for example, remove the type signature and ask ghci to infer the type:
$ ghci
GHCi, version 7.6.2: http://www.haskell.org/ghc/ :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Prelude> :{
Prelude| let setOffsetTime [] = 200
Prelude| setOffsetTime (x : xs) = read x :: Int
Prelude| :}
Prelude> :t setOffsetTime
setOffsetTime :: [String] -> Int
Prelude> :q
Leaving GHCi.
$
And indeed,
setOffsetTime :: [String] -> Int
setOffsetTime [] = 200
setOffsetTime (x : xs) = read x :: Int
compiles fine.
If you want a slightly more general type, you can drop the ascription :: Int from the second case. The above method then tells you that you can write
setOffsetTime :: (Num a, Read a) => [String] -> a
setOffsetTime [] = 200
setOffsetTime (x : xs) = read x
From the comment that you added to your question, I understand that you want your function to return a floating-point number. In that case, you can write
setOffsetTime :: [String] -> Float
setOffsetTime [] = 200.0
setOffsetTime (x : xs) = read x
or, more general:
setOffsetTime :: (Fractional a, Read a) => [String] -> a
setOffsetTime [] = 200.0
setOffsetTime (x : xs) = read x

Difference between `(Integer a) => a -> Bool` and ` Integer -> Bool`?

I wrote my first program in Haskell today. It compiles and runs successfully. And since it is not a typical "Hello World" program, it in fact does much more than that, so please congrats me :D
Anyway, I've few doubts regarding my code, and the syntax in Haskell.
Problem:
My program reads an integer N from the standard input and then, for each integer i in the range [1,N], it prints whether i is a prime number or not. Currently it doesn't check for input error. :-)
Solution: (also doubts/questions)
To solve the problem, I wrote this function to test primality of an integer:
is_prime :: Integer -> Bool
is_prime n = helper n 2
where
helper :: Integer -> Integer -> Bool
helper n i
| n < 2 * i = True
| mod n i > 0 = helper n (i+1)
| otherwise = False
It works great. But my doubt is that the first line is a result of many hit-and-trials, as what I read in this tutorial didn't work, and gave this error (I suppose this is an error, though it doesn't say so):
prime.hs:9:13:
Type constructor `Integer' used as a class
In the type signature for `is_prime':
is_prime :: Integer a => a -> Bool
According to the tutorial (which is a nicely-written tutorial, by the way), the first line should be: (the tutorial says (Integral a) => a -> String, so I thought (Integer a) => a -> Bool should work as well.)
is_prime :: (Integer a) => a -> Bool
which doesn't work, and gives the above posted error (?).
And why does it not work? What is the difference between this line (which doesn't work) and the line (which works)?
Also, what is the idiomatic way to loop through 1 to N? I'm not completely satisfied with the loop in my code. Please suggest improvements. Here is my code:
--read_int function
read_int :: IO Integer
read_int = do
line <- getLine
readIO line
--is_prime function
is_prime :: Integer -> Bool
is_prime n = helper n 2
where
helper :: Integer -> Integer -> Bool
helper n i
| n < 2 * i = True
| mod n i > 0 = helper n (i+1)
| otherwise = False
main = do
n <- read_int
dump 1 n
where
dump i x = do
putStrLn ( show (i) ++ " is a prime? " ++ show (is_prime i) )
if i >= x
then putStrLn ("")
else do
dump (i+1) x
You are misreading the tutorial. It would say the type signature should be
is_prime :: (Integral a) => a -> Bool
-- NOT Integer a
These are different types:
Integer -> Bool
This is a function that takes a value of type Integer and gives back a value of type Bool.
Integral a => a -> Bool
This is a function that takes a value of type a and gives back a value of type Bool.
What is a? It can be any type of the caller's choice that implements the Integral type class, such as Integer or Int.
(And the difference between Int and Integer? The latter can represent an integer of any magnitude, the former wraps around eventually, similar to ints in C/Java/etc.)
The idiomatic way to loop depends on what your loop does: it will either be a map, a fold, or a filter.
Your loop in main is a map, and because you're doing i/o in your loop, you need to use mapM_.
let dump i = putStrLn ( show (i) ++ " is a prime? " ++ show (is_prime i) )
in mapM_ dump [1..n]
Meanwhile, your loop in is_prime is a fold (specifically all in this case):
is_prime :: Integer -> Bool
is_prime n = all nondivisor [2 .. n `div` 2]
where
nondivisor :: Integer -> Bool
nondivisor i = mod n i > 0
(And on a minor point of style, it's conventional in Haskell to use names like isPrime instead of names like is_prime.)
Part 1: If you look at the tutorial again, you'll notice that it actually gives type signatures in the following forms:
isPrime :: Integer -> Bool
-- or
isPrime :: Integral a => a -> Bool
isPrime :: (Integral a) => a -> Bool -- equivalent
Here, Integer is the name of a concrete type (has an actual representation) and Integral is the name of a class of types. The Integer type is a member of the Integral class.
The constraint Integral a means that whatever type a happens to be, a has to be a member of the Integral class.
Part 2: There are plenty of ways to write such a function. Your recursive definition looks fine (although you might want to use n < i * i instead of n < 2 * i, since it's faster).
If you're learning Haskell, you'll probably want to try writing it using higher-order functions or list comprehensions. Something like:
module Main (main) where
import Control.Monad (forM_)
isPrime :: Integer -> Bool
isPrime n = all (\i -> (n `rem` i) /= 0) $ takeWhile (\i -> i^2 <= n) [2..]
main :: IO ()
main = do n <- readLn
forM_ [1..n] $ \i ->
putStrLn (show (i) ++ " is a prime? " ++ show (isPrime i))
It is Integral a, not Integer a. See http://www.haskell.org/haskellwiki/Converting_numbers.
map and friends is how you loop in Haskell. This is how I would re-write the loop:
main :: IO ()
main = do
n <- read_int
mapM_ tell_prime [1..n]
where tell_prime i = putStrLn (show i ++ " is a prime? " ++ show (is_prime i))