I'm new to SML and I'm trying to run some code from github in SML/NJ. I'm currently trying to call the function
fun dates_in_month(xs : (int * int * int) list, n : int) =
if null xs then
[]
else if #2 (hd xs) = n then
(hd xs)::dates_in_month(tl xs, n)
else
dates_in_month(tl xs, n)
like so
dates_in_month(3::2::1::nil, 5)
but I get the following error message on SML/NJ 110.97
stdIn:8.1-8.31 Error: operator and operand do not agree [overload - bad instantiation]
operator domain: (int * int * int) list * int
operand: 'Z[INT] list * 'Y[INT]
in expression:
dates_in_month (3 :: 2 :: <exp> :: <exp>, 5)
This issue arises because you're currently trying to call a function of type (int * int * int) list * int -> (int * int * int) list with a parameter of type int list * int. That is to say, the first element of your tuple is of the incorrect type.
You instead want a list of 3-tuples of int. You could construct one like so:
(1, 2, 3) :: (4, 5, 6) :: nil
or a bit briefer as
[(1, 2, 3), (4, 5, 6)]
Note that here the elements of the list are 3-tuples of int as opposed to just ints like you had previously.
The type (int * int * int) list refers to something that looks like:
[(1,2,3), (-69,0,69), (10,100,1000)]
What you are currently passing to the function is:
[3,2,1]
This is because the operator :: is used to construct lists, which are DISTINCT from tuples like (1,2,3). (Basically, a variable of type list can be of any length, whereas a tuple is of a fixed length).
Related
I have the following code to compute the Hofstadter H Sequence, but I am getting an overload conflict error message. I am fairly new to SML therefore i am sure what the error is referring to.
(* Hofstadter H-Sequence *)
fun H(0) = [0]
| H(n) = if n = 0 then [0] else x :: (n - H(H(H(n - 1))));
My goal is to insert the value of each iteration into a list and display it.
Ex: H 10; -->[1, 1, 2, 3, 4, 4, 5, 5, 6, 7]
You're trying to write a function with the type int -> int list.
(It's a good idea to think about the types while writing, even though SML will infer them. A good type system is like autofocus for the mind.)
You can't subtract the result of this function from a number (n - H(...)) since it is a list, nor can you pass a list to to this function – H(H(n - 1)) – since it wants a number.
(And where did the first element, x, come from?)
Start simple, with a function that's just the definition of H(n):
fun H 0 = 0
| H n = n - H(H(H(n-1)))
Test:
- H 0;
val it = 0 : int
- H 1;
val it = 1 : int
- H 2;
val it = 1 : int
- H 4;
val it = 3 : int
Then use that to build a list incrementally.
This variant uses a locally defined helper function that uses the current index and a counter:
fun H_seq n = let fun H_seq' m e =
if m < e
then (H m) :: (H_seq' (m+1) e)
else []
in
H_seq' 0 n
end;
Example:
- H_seq 10;
val it = [0,1,1,2,3,4,4,5,5,6] : int list
This is pretty inefficient, but fixing that is part of the more advanced course...
This question already has answers here:
No instance for (Floating Int)
(3 answers)
Closed 6 years ago.
I am trying to do something like in Haskell:
mkList start end nb_chunck will output [start, boun1, bound2, bound3 ..., end]
However I don't want to split the list in equal-size chunk but to follow a logarithmic scale.
The C algorithm I want to transform in Haskell is availabke here: How to get a logarithmic distribution from an interval
I don't really know how to do it.
Here's what I have attempted so far:
mkList :: Int -> Int -> Int -> Int -> Int -> [Int]
mkList _ _ _ _ 7 = []
mkList lower upper start end n = [lower, ((fromIntegral (log(2 + (fromIntegral n :: Int)) )+start) * scale)] ++ (mkList (fromIntegral(((fromIntegral (log(2 + (fromIntegral n :: Int)) )+start) * scale)+1) :: Int) ((fromIntegral (log(2 + (fromIntegral (n) :: Int)) )+start) * scale) (start) end (fromIntegral (n+1) :: Int)) where
scale = (end - start) `quot` floor(log(1 + (6)))
However, I can't validate this code, because when I compile, error messages pop up:
haskell_par3.hs:71:58:
No instance for (Floating Int) arising from a use of `log'
Possible fix: add an instance declaration for (Floating Int)
In the first argument of `fromIntegral', namely
`(log (2 + (fromIntegral n :: Int)))'
In the first argument of `(+)', namely
`fromIntegral (log (2 + (fromIntegral n :: Int)))'
In the first argument of `(*)', namely
`(fromIntegral (log (2 + (fromIntegral n :: Int))) + start)'
ghc -cpp: /usr/hs/ghc/7.6.3/bin/ghc failure (return code=1)
I've tried to make use of fromIntegral at different spots but it didn't help, as seen in other answered questions on StackOverflow.
So I'm asking two things:
Do you have any precise idea of how I could fix these compilation errors? (I know it has something to do with fromIntegral, but I can't get rid of this error).
And more important: Do you think this code may achieve what I want to do? If no, do you have any suggestions?
you can do something like this to create a log scale intervals
scale k n = map (floor . (*k) . (/(log n)) . log) [1..n]
e.g.
scale 100 9
[0,31,50,63,73,81,88,94,100]
and use the indices to partition the array by start/end indices.
You can cast the output to [Int] since floor convert it to an Integral type
Prelude> scale 10 3 :: [Int]
[0,6,10]
Prelude> :t it
it :: [Int]
How to compute the product of two polynomials ?
For example: x^3 + 3x^2 +0.2x and 2x^4 + 3
First I made a type
Type term = {coefficient:int; name:string; exponent:int};;
Type polynomials = term list;;
then I made a function calculate coefficient
let product l l' =
List.concat (List.map (fun e -> List.map (fun e' -> (e*e')) l'.coefficient)
l.coefficient);;
This is where I get stuck. I guess I can use the same function for exponent as well,but the question is asking writing a polynomials function with one param, which means two polynomials will be in the same variable
Can someone help me out here
You seem to be saying that you're asked to write a function to multiply two polynomials, but the function is supposed to have just one parameter. This, indeed, doesn't make a lot of sense.
You can always use a tuple to bundle any number of values into a single value, but there's no reason to do this (that I can see), and it's not idiomatic for OCaml.
Here's a function with one parameter (a pair) that multiplies two ints:
# let multiply (a, b) = a * b;;
val multiply : int * int -> int = <fun>
# multiply (8, 7);;
- : int = 56
(As a separate comment, the code you give doesn't compile.)
I am making a sudoku solving program and I have a potentialNbrsAt function that gets the numbers that could be at position x y.
Now, I am trying to get the intersect of each lists of potential numbers in a column. Something like the onlyOnePlaceForNbrInCol function bellow.
Code:
potentialNbrsAt :: Int -> Int -> Sudoku -> [Int]
potentialNbrsAt x y sudoku = intersect rowMissingNbrs $ intersect colMissingNbrs sqrMissingNbrs
where rowMissingNbrs = getMissingNbrs $ getRow y sudoku
colMissingNbrs = getMissingNbrs $ getCol x sudoku
sqrMissingNbrs = getMissingNbrs $ getSquare squareIndex sudoku
squareIndex = 3 * (y `div` 3) + (x `div` 3)
onlyOnePlaceForNbrInCol :: Int -> Int -> Sudoku -> Bool
onlyOnePlaceForNbrInCol colIndex nbr sudoku = -- What goes here? Some pointers please???
I think onlyOnePlaceForNbrInCol should, at some point, call potentialNbrsAt with each numbers from 0 to 8 as an argument for y. Telling me how to do this would greatly help.
What about [ potentialNbrsAt x y sudoku | y <- [0..8] ] ? This gives you a list of all the results for such values of y.
So you're trying to determine whether all of the numbers [0..8] fulfill a given predicate.
Why does the exponential operator use float variables in OCaml?
Shouldn't it allow int variables too?
# 3**3;;
Error: This expression has type int but an expression was expected of type
float
Works:
# 3.0**3.0;;
- : float = 27.
So, the existing answers go into how to get around this, but not into why it is the case. There are two main reasons:
1) OCaml doesn't have operator aliasing. You can't have two operators that do the "same thing", but to different types. This means that only one kind of number, integers or floats (or some other representation) will get to use the standard ** interface.
2) pow(), the exponentiation function has historically been defined on floats (for instance, in Standard C).
Also, for another way to get around the problem, if you're using OCaml Batteries included, there is a pow function defined for integers.
You can use int
let int_exp x y = (float_of_int x) ** (float_of_int y) |> int_of_float
There's a similar question: Integer exponentiation in OCaml
Here's one possible tail-recursive implementation of integer exponentiation:
let is_even n =
n mod 2 = 0
(* https://en.wikipedia.org/wiki/Exponentiation_by_squaring *)
let pow base exponent =
if exponent < 0 then invalid_arg "exponent can not be negative" else
let rec aux accumulator base = function
| 0 -> accumulator
| 1 -> base * accumulator
| e when is_even e -> aux accumulator (base * base) (e / 2)
| e -> aux (base * accumulator) (base * base) ((e - 1) / 2) in
aux 1 base exponent