I was thinking of a way to represent algebraic numbers in Haskell as a stream of approximations. You could probably do this by some root finding algorithm. But that's no fun. So you could add x to the polynomial, reducing the problem to finding it's fixed points.
So if you have a function in Haskell like
f :: Double -> Double
f x = x ^ 2 + x
I don't conceptually understand why fix doesn't work, which is to say, I can easily verify for myself that it doesn't work, but isn't 0 the true least fixed point of f? Is there another simple (as in definition size) fixed point function that would work?
Here is the implementation of the fix function:
fix :: (a -> a) -> a
fix f = let x = f x in x
It doesn't work for primitive types like Double. It's intended for types that have a more complex structure to them. For instance:
g :: Maybe Int -> Maybe Int
g i = Just $ case i of
Nothing -> 3
Just _ -> 4
This function will work with fix because it yields information about its result faster than it reads its input. in other words, the Just portion is known without looking at i at all, which enables it to reach a fixed point.
When your function is Double -> Double, and examines its input, fix won't work because there's no way to partially evaluate a Double.
Related
I am trying to implement a generator, selector pattern to approximately calculate square roots in haskell
My generator looks like this:
generator :: (Double -> Double) -> Double -> [Double]
generator f a = generator f (f a)
My selector:
selector :: Double -> [Double] -> Double
selector eps (a : b : r)
| abs(a - b) <= eps = b
| otherwise = selector eps (b : r)
And the approx function:
next :: Double -> Double -> Double
next n x = (x + n/x) / 2
Calling this like selector 0.1 (generator (next 5) 2)
should give me ...(next 5( next 5 (next 5 2))) so [2.25, 2.23611111111111, 2.2360679779158,...] since my eps parameter is 0.1 abs(a - b) <= eps should be true on the first execution giving me 2.23611111111111 as a result. I do however end in a endless loop.
Could somebody explain to me what is wrong in the implementation of those functions?
Thanks in advance
This definition
generator f a = generator f (f a)
never generates any list elements: it gets stuck into an infinite recursion instead. You probably want
generator f a = a : generator f (f a)
which makes a to be the first element, followed by all the others we generate using recursion.
It could also be beneficial to avoid putting unevaluated thunks in the list. To avoid that, one could use
generator f a = a `seq` (a : generator f (f a))
so that a is evaluated early. This should not matter much in your code, since the
selector immediately evaluates the thunks as soon as they are generated.
Your generator function is missing the a:, as chi's answer correctly points out. However, there's a better solution than just adding that. Get rid of generator altogether, and use the built-in method iterate instead (or iterate' from Data.List if you want to avoid unevaluated thunks). These methods have the same behavior that you want from generate, but support optimizations like list fusion that your own method won't. And of course, there's also the advantage that it's one less function that you have to write and maintain.
Can someone explain to me step by step what this function means?
select :: (a->a->Bool) -> a -> a -> a
As the comments pointed out, this is not a function definition, but just a type signature. It says, for any type a which you are free to choose, this function expects:
A function that takes two values of type a and gives a Bool
Two values of type a
and it returns another value of type a. So for example, we could call:
select (<) 1 2
where a is Int, since (<) is a function that takes two Ints and returns a Bool. We could not call:
select isPrefixOf 1 2
because isPrefixOf :: (Eq a) => [a] -> [a] -> Bool -- i.e. it takes two lists (provided that the element type supports Equality), but numbers are not lists.
Signatures can tell us quite a lot, however, due to parametericity (aka free theorems). The details are quite techincal, but we can intuit that select must return one of its two arguments, because it has no other way to construct values of type a about which it knows nothing (and this can be proven).
But beyond that we can't really tell. Often you can tell almost certainly what a function does by its signature. But as I explored this signature, I found that there were actually quite a few functions it could be, from the most obvious:
select f x y = if f x y then x else y
to some rather exotic
select f x y = if f x x && f y y then x else y
And the name select doesn't help much -- it seems to tell us that it will return one of the two arguments, but the signature already told us that.
From my understanding, the Maybe type is something you can combine with another type. It lets you specify a condition for the inputs that you combined it with using the "Just... Nothing" format.
an example from my lecture slides is a function in Haskell that gives the square root of an input, but before doing so, checks to see if the input is positive.:
maybe_sqrt :: Maybe Float -> Maybe Float
maybe_sqrt maybe_x = case maybe_x of
Just x
| x >= 0 -> Just (sqrt x)
| otherwise -> Nothing
Nothing -> Nothing
However, I don't understand why this function uses both cases and guards. Why can't you just use guards, like this?:
maybe_sqrt :: Maybe Float -> Maybe Float
maybe_sqrt x
| x >= 0 = Just (sqrt x)
| otherwise = Nothing
the Maybe type is something you can combine with another type
Maybe is not a type†. It's a type constructor, i.e. you can use it to generate a type. For instance, Maybe Float is a type, but it's a different type from Float as such. A Maybe Float can not be used as a Float because, well, maybe it doesn't contain one!
But to calculate the square root, you need a Float. Well, no problem: in the Just case, you can just unwrap it by pattern matching! But pattern matching automatically prevents you from trying to unwrap a Float out of a Nothing value, which, well, doesn't contain a float which you could compare to anything.
Incidentally, this does not mean you to need trace every possible failure by pattern matching, all the way through your code. Luckily, Maybe is a monad. This means, if your function was a Kleisli arrow
maybe_sqrt :: Float -> Maybe Float
maybe_sqrt x
| x >= 0 = Just (sqrt x)
| otherwise = Nothing
(which is fine because it does accept a plain float) then you can still use this very easily with a Maybe Float as the argument:
GHCi> maybe_sqrt =<< Just 4
Just 2.0
GHCi> maybe_sqrt =<< Just (-1)
Nothing
GHCi> maybe_sqrt =<< Nothing
Nothing
†As discussed in the comments, there is some disagreement on whether we should nevertheless call Maybe type, or merely a type-level entity. As per research by Luis Casillas, it's actually rather Ok to call it a type. Anyway: my point was that Maybe Float is not “an OR-combination of the Maybe type (giving failure) and the Float type (giving values)”, but a completely new type with the structure of Maybe a and the optionally-contained elements of Float.
If your type were maybe_sqrt :: Float -> Maybe Float then that is how you would do it.
As it is, consider: what should your function do if your input is Nothing? Probably, you would want to return Nothing -- but why should your compiler know that?
The whole point of an "option" type like Maybe is that you can't ignore it -- you are required to handle all cases. If you want your Nothing cases to fall through to a Nothing output, Haskell provides a (somewhat) convenient facility for this:
maybe_sqrt x_in = do
x <- x_in
if x >= 0 then return sqrt x
else Nothing
This is the Maybe instance of Monad, and it does what you probably want. Any time you have a Maybe T expression, you can extract only the successful Just case with pattern <- expression. The only thing to remember is that non-Maybe bindings should use let pattern = expression instead.
This is more an extended comment than an answer. As leftaroundabout indicated, Maybe is an instance of Monad. It's also an instance of Alternative. You can use this fact to implement your function, if you like:
maybe_sqrt :: Maybe Float -> Maybe Float
maybe_sqrt maybe_x = do
x <- maybe_x
guard (x >= 0)
pure (sqrt x)
This is also more an extended comment (if this is your first time working with Maybe, you may not have encountered type classes yet; come back when you do). As others already said, x has type Maybe Float. But writing x >= 0 doesn't require x to be Float. What does it actually require? >= has type (Ord a) => a -> a -> Bool, which means it works for any types which are instances of Ord type class (and Maybe Float is one), and both arguments must have the same type. So 0 must be a Maybe Float as well! Haskell actually allows this, if Maybe Float belongs to the Num type class: which it doesn't in the standard library, but you could define an instance yourself:
instance Num a => Num (Maybe a) where
fromInteger x = Just (fromInteger x)
# this means 0 :: Maybe Float is Just 0.0
negate (Just x) = Just (negate x)
negate Nothing = Nothing
Just x + Just y = Just (x + y)
_ + _ = Nothing
# or simpler:
# negate = fmap negate
# (+) = liftA2 (+)
# similar for all remaining two argument functions
...
Now x >= 0 is meaningful. sqrt x is not; you'll need instances for Floating and Fractional as well. Of course, Just (sqrt x) will be Maybe (Maybe a), not Maybe a! But just sqrt x will do what you want.
The problem is that it works kind of by coincidence that Nothing >= 0 is False; if you checked x <= 0, Nothing would pass.
Also, it's generally a bad idea to define "orphan instances": i.e. the instance above should really only be defined in the module defining Maybe or in the module defining Num.
I am just starting to program in Haskell, and I came across the following definition:
calculate :: Float -> Float -> Maybe Float
Maybe a is an ordinary data type defined as:
data Maybe a = Just a | Nothing
There are thus two possibilities: or you define a value of type a as Just a (like Just 3), or Nothing in case the query has no answer.
It is meant to be defined as a way to define output for non-total functions.
For instance: say you want to define sqrt. The square root is only defined for positive integers, you can thus define sqrt as:
sqrt x | x >= 0 = Just $ ...
| otherwise = Nothing
with ... a way to calculate the square root for x.
Some people compare Nothing with the "null pointer" you find in most programming languages. By default, you don't implement a null pointer for data types you define (and if you do, all these "nulls" look different), by adding Nothing you have a generic null pointer.
It can thus be useful to use Maybe to denote that it is possible no output can be calculated. You could of course also error on values less than 0:
sqrt x | x >= 0 = Just $ ...
| otherwise = error "The value must be larger or equal to 0"
But errors usually are not mentioned in the type signature, nor does a compiler have any problem if you don't take them into account. Haskell is also shifting to total functions: it's better to always try at least to return a value (e.g. Nothing) for all possible inputs.
If you later want to use the result of a Maybe a, you for instance need to write:
succMaybe :: Maybe Int -> Maybe Int
succMaybe (Just x) = Just (x+1)
succMaybe _ = Nothing
But by writing Just for the first case, you somehow warn yourself that it is possible that Nothing can occur. You can also get rid of the Maybe by introducing a "default" value:
justOrDefault :: a -> Maybe a -> a
justOrDefault _ (Just x) = x
justOrDefault d _ = d
The builtin maybe function (note the lowercase), combines the two previous functions:
maybe :: b -> (a -> b) -> Maybe a -> b
maybe _ f (Just x) = f x
maybe z _ Nothing = z
So you specify a b (default value) together with a function (a -> b). In case Maybe a is Just x, the function is applied to it and returned, in case the input value is Nothing, the default value will be used.
Working with Maybe a's can be hard, because you always need to take the Nothing case into account, to simplify this you can use the Maybe monad.
Tom Schrijvers also shows that Maybe is the successor function in type algebra: you add one extra value to your type (Either is addition and (,) is the type-algebraic equivalent of multiplication).
I have function in haskell (lets call it 'dumb') which calls 3 different functions. These three different functions return different types, for example, a boolean or a list of booleans. How can I define function 'dumb' to either return a boolean or a list of booleans?
data Sumtype = givelist Integer | getprod Integer
prod :: Int -> Int
prod x = x*3
listnums :: Int -> [Int]
listnums x = [1...x]
dumb :: Sumtype -> (what comes here..?)
dumb (givelist x) -> listnums x
dum (getprod x) -> prod x
You make it return Either Boolean [Boolean]. But I'm suspicious about your motives. It sounds like an X/Y problem.
You're probably looking for the the Either type, although with it your function will return Either values. It's defined like this:
data Either a b = Left a | Right b
When you want to define a function that can return either a Bool or a list of Bools its type should look something like this:
dumb :: Either Bool [Bool]
In this case 'dumb' will be a function that doesn't take any arguments and return either a Bool or a list of Bools. In the function's body you can return a Bool like this:
Left bool
Or a list of bools like this:
Right [bool]
You can see a concrete example here: http://en.wikibooks.org/wiki/Haskell/More_on_datatypes#More_than_one_type_parameter
All that said though, the reason Sebastian asked you for more details is that Either is rarely used outside of error handling (AFAIK I know anyway). It's possible that in your case you don't really need it at all, but we can't be sure unless you tell us more about the other functions you use in 'dumb' and about your goals.
Unrelated Probems
It appears you are a beginner - welcome to Haskell! I strongly suggest you read and work through one of the many tutorials as that is more efficient and complete than asking individual questions.
Syntax
Let's start with correcting the syntax errors. Constructors, such as Givelist and Getprod must start with a capital letter. The function dumb was typo'ed once. Function definitions use = and not ->.
Types
Now we have type errors to address. The Sumtype uses Integer and you then switch to using Int. Lets just stick with Integer for simplicity.
With these fixes we get:
data Sumtype = Givelist Integer | Getprod Integer
prod :: Integer -> Integer
prod x = x*3
listnums :: Integer -> [Integer]
listnums x = [1...x]
dumb :: Sumtype -> (what comes here..?)
dumb (Givelist x) = listnums x
dumb (Getprod x) = prod x
The Question
You want to know "what comes here" where 'here' is the result type. As written, the function is actually invalid. One definition yields a list of integers, [Integer], while the other yields a single integer Integer. One solution is to use a sum type such as Either Integer [Integer] - this is very much like your pre-existing Sumtype:
dumb :: Sumtype -> Either Integer [Integer]
So now we need to return a constructor of Either in our function definitions. You can lookup the documentation or use :info Either in GHCi to learn the constructors if you don't have them memorized.
dumb (Givelist x) = Right (listnums x)
dumb (Getprod x) = Left (prod x)
Notice we had to use Left for the second case which returns an Integer, because the first type we wrote after Either (the left type) is Integer.