In my project I ended up using the following unfold function in several places.
unfold :: (a -> Either b a) -> a -> b
unfold f x = either id (unfold f) $ f x
It feels like a very general recursion pattern (simply apply a function on values of type a until you get a Right b), but I'm failing to find such a function somewhere with Hoogle.
Is it really not defined anywhere?
This function is implemented in the extra package as Control.Monad.Extra.loop.
loop :: (a -> Either a b) -> a -> b
A looping operation, where the predicate returns Left as a seed for the next loop or Right to abort the loop.
loop (\x -> if x < 10 then Left $ x * 2 else Right $ show x) 1 == "16"
The extra package also provides a monadic version loopM.
As a future note, in addition to searching Hoogle for a function by name, you can simply plug in a type signature and Hoogle will look for functions matching this signature. I found the above function by entering (a -> Either a b) -> a -> b into Hoogle as such.
If you want a version with the type arguments flipped from the extra version, there's also iterateM_ from the monad-loops package.
iterateM_ :: Monad m => (a -> m a) -> a -> m b
This doesn't solve your problem in one step, but it's capturing the underlying pattern of recursion more accurately.
Note that there's nothing specific to Either going on in there, which does make it a bit trickier to find. I found it via hoogle by name. I didn't know if it existed, but I knew that if something by that name did exist, it would solve your problem. I derived that starting from iterate in base. It repeatedly applies a function to the output from the previous step, with an initial seed value, like you wanted. But you wanted to be able to short circuit at any time, which Either's monad instance does for you, so a name like iterateM would make more sense. Except you don't care about all the intermediate results, so iterateM_ would be the name that makes sense.
(Also, it turns out everything that does produce the intermediate results requires a streaming system to do it. Which makes sense in retrospect, but explains why hoogle changed what packages it was showing results from entirely when I added the "_" at the end.)
Now, as far as this not actually being exactly the type you want: yes, a bit was lost when it became more generic. But that can be recovered in a bit of an interesting way. Look back at the type of iterateM_, and notice that the return value is m b, and b wasn't mentioned anywhere previously in the type. This is subtle but significant information. Since there's no way a function can just make up a value of a polymorphic type it knows nothing about, it means that it can never produce such a value at all. Let's inline Either in the type and see what happens: iterateM_ :: (a -> Either r a) -> a -> Either r b. How can we safely convert Either r b to r? Well, we know we can choose anything at all for b, because it can't exist. And fortunately, there are tools to handle this.
base contains a module, Data.Void, that helps here. It has a type Void that has no constructors. You can think of it as a type-level signifier that something can't happen. And since it can't happen, there's an adapter to make things fit together on the value level as needed: absurd :: Void -> a. The name comes from logic, based on the idea that once the impossible happens once you're in a silly case and might as well allow anything else to happen. At an operational level, you can have values of type Void in Haskell because undefined :: Void will type-check. But absurd is perfectly safe regardless - it forces its argument to be evaluated. Since any time it actually is evaluated the argument must be a bottom value of some sort, this remains type-safe.
So how does this fit in with iterateM_? Well, things have worked out so there's an Either r b value that we know must be the Left constructor, but using fromLeft feels dirty. But what's interesting here is that while r is constrained by context, b is still completely polymorphic. We can choose whatever type we want for it, because we know it'll never happen. So choose Void, giving either id absurd :: Either r Void -> r
unfold :: (a -> Either b a) -> a -> b
unfold f x = either id absurd $ iterateM_ f x
Maybe that's not even an improvement on your original. Maybe it is - the recursion is captured in a combinator instead of explicit. And for what it's worth, that combinator captures a more general pattern of recursion than something specific to Either. But that has the cost of introducing an extra conversion step to realign the types afterwards, and that step ends up involving a new idea that wasn't necessary before. On the plus side, it makes a nice illustration for how to use the type system to communicate things clearly.
Related
Is there a common name/type for a lens-like object that does not satisfy the property of getting out what you put in? For example something like a listLength :: Lens [a] Int where if you put in a length shorter than that of the source list you get a shortened list, but if you put in a longer length the original length is preserved.
A lens is not just a function with the type forall f. Functor f => (a -> f b) -> s -> f t — it's a function with that type that obeys certain laws. In particular, (as documented in the lens docs):
You get back what you put in,
Putting back what you got doesn't change anything, and
Setting twice is the same as setting once.
If your function doesn't obey those laws, then it's just a function with a type that's similar to a lens.
In your particular example, listLength breaks the first and third laws, so it's not a lens. That said, it would work just fine as a Getter, which I think is the only principle thing we can say about it.
More generally, it doesn't really make sense to ask about things that lack laws, as things tend to be defined by what laws they obey rather than what they don't obey. For example, I pointed out that listLength makes a perfectly good Getter because it consistently extracts a value out of the [a] input.
So, I'll ask you: What distinguishes it from a function listZero :: Lens [a] Int that always emits 0? Can you come up with a general law that listLength obeys that listZero doesn't? If so, then you have something to actually look for in the current literature: that is, listLength is one of a set of functions that obeys some (possibly interesting) law. If not, then you just have a function with a type that makes it look like a lens.
As a Haskell beginner, I'm curious about best practices. In particular, in the absence of other requirements, is it better to associate related function arguments using tuples, or keep them "naked"?
E.g.
vector :: Float -> Float -> Float -> Vector
vs.
vector :: (Float, Float, Float) -> Vector
The reason I ask is that sometimes aspects of a parameter (e.g. x coordinate in a 2D or 3D point or vector) are normally bound up with other parameters (e.g. the y & z coordinates). I can see how pattern-matching can be used in both cases, but I'm curious to know whether there are serious implications "down the track" to using tuples or distinct parameters.
When other parameters are involved, the use of tuples seems to make it clear that a certain set of parameters are associated with each other. But it also makes the code more verbose when functions take just the tuple as a parameter.
I would recommend, as a rule of thumb, to never put tuples in the arguments of a function signature.
Why? Well, if the point is to group stuff together, then tuples do a rather measly job at it. Sure, you could use nested tuples and type synonyms to explain what they mean, but all of that is brittle and much better and safer done with proper record types. As you've identified, the x- and y-components of a vector usually come together. Well, not only that, in many a sense it is a good idea to keep the x- and y-components completely hidden from any interesting code. That's exactly what the Vector type should accomplish. (Which should probably be called Vector3 or ℝ³ instead.) And the only purpose of the vector function should be to assemble one of those from the components. Well, if that's the only thing it does, then the three components are the only arguments, and there's no point grouping them together any further... that's basically just putting a single suitcase into another transport box. Better just use the right container right away as a single wrapper.
vector3 :: Float -> Float -> Float -> Vector3
An example of a tuple in a signature of a commonly used function is
randomR :: (Random a, RandomGen g) => (a,a) -> g -> (a,g)
Why is this a bad idea? Well, you're using a tuple to denote an interval... but also in the result to denote something completely different, a grouping of the obtained random value with the updated generator. The proper way to do this is to either have a type that properly expresses what it is
data Interval a = Interval {lowerBound, upperBound :: a}
randomR :: (Random a, RandomGen g) => Interval a -> g -> (a,g)
...or better, separate the concerns, i.e. that manual state-threading should be hidden in a suitable monad – such as RVar. At that point the range limits become the only arguments, thus you don't need to group them together anymore!
uniform :: Distribution Uniform a => a -> a -> RVar a
That doesn't mean you should never use tuples at all. For result values, the currying mechanism doesn't work as easily†, so if you have a function that gives back two results but there's not really any meaningful interpretation for what those two values represent together, well, give back a tuple.
Furthermore, if you're grouping together completely abstract types, you can't possibly have an interpretation for what they mean together. That's the reason why zip :: [a] -> [b] -> [(a,b)] gives a list of tuples.
†You can also have multi-result functions with tuples. For that, you need to use continuation-passing style, for example splitAt :: Int -> [a] -> ([a],[a]) becomes splitAt' :: Int -> [a] -> ([a] -> [a] -> r) -> r.
There are no implications down the line. A function that can accept one argument first and then another one later, is said to be curried. A function that accepts a tuple as an argument is said to be uncurried. You can convert between the two using curry and uncurry. Feel free to extend this definition to three parameters and define new functions curry3 f a b c= f(a,b,c) and uncurry3 f (a,b,c)= f a b c.
In this case, I would going for a named datatype for most uses. In fact, you already seem to have a Vector type. Making your constructor, vector, accept a triple seems like an excellent idea. That way, those who try to use it to construct a 2D vector will get the most helpful message from the type checker.
In Haskell I find it difficult to completely grasp the purpose of a kind system, and what it truly adds to the language.
I understand having kinds adds safety.
For example consider fmap :: (a -> b) -> f a -> f b vs a monokinded version of it fmap2 :: (a -> b) -> p -> q.
My understanding is that, thanks to the kind system, I can specify beforehand with higher detail what the shape of the data should be. It is better, as the type checker can check more, and stricter requirements will make it less likely that users will mess up with types. This will reduce the likelihood of programming errors. I believe this is the main motivation for kinds but I might be wrong.
Now I think fmap2 can have the same implementation as fmap, since its types are unconstrained. Is it true?
Could one just replace all multi kinded types in the base/ghc library by mono kinded ones, and would it still compile correctly?
To clarify a little bit I mean that for a class like:
class Functor f where
fmap :: (a -> b) -> f a -> f b
(<$) :: a -> f b -> f a
I might replace it by something like
class Functor a b p q where
fmap :: (a -> b) -> p -> q
(<$) :: a -> q -> p
This way for a Functor instance like
instance Functor [] where fmap = map
I might replace it by
instance Functor a b p q where fmap = map
Remark: This wont work as is because i also need to modify map and go down the dependency chain. Will think more about this later..
I'm trying to figure out if kinds add more than just safety? Can I do something with multi kinded types that I cannot do with mono kinded ones?
Remark: Here I forgot to mention i'm usually using some language extensions, typically to allow more flexibility in writing classes.
When doing vanilla haskell kinds can be really meaningful thing to use.
But when I start using type families, and a few of other extensions it becomes much less clear that I need kinds at all.
I have in mind that there is some monotraversable library which reimplements many standard library functions using single kinded types, and type families to generalize signatures. That's why my intuition is that multi kinded variables might not really add that much expressive power after all, provided one uses type families. However a drawback of doing this is that you lose type safety. My question is do you really only lose just that, or do you really lose something else.
Let's back up. It seems like you think that because the signature
id2 :: a -> b
is more general than
id :: a -> a
that id2 could have the same implementation as id. But that's not true. In fact id2 has no total implementation (any implementation of id2 involves an infinite loop or undefined).
The structure of generality creates a "pressure", and this pressure is what we must navigate to find the right type for something. If f is more general than g, that means that anywhere g could be used, f could also but it also means that any implementation of f is a valid implementation of g. So at the use site it goes one direction, at the definition site it goes the other.
We can use id2 anywhere we could have used id, but the signature of id2 is so general that it is impossible to implement. The more general a signature gets, the more contexts it can be used in, but also the less likely it is to have an implementation. I would say a main goal of a good type signature is to find the level of generality where there are as few as possible implementations of your intended function, without making it impossible to write altogether.
Your proposed signature fmap2 :: (a -> b) -> p -> q is, like id2, so general that it is impossible to implement. The purpose of higher-kinded types is to give us the tools to have very general signatures like fmap, which are not too general like fmap2.
It's not clear to me the difference between makeLense and makePrisms?
I'm aware that when we want to access a nested structure/data then use makeLense like this:
data Point = Point { _x :: Int, _y :: Int}
data Test= Test {_name :: String, _position :: Point}
makeLenses ''Point
makeLenses ''Test
Then we can access or modify the component of Test or Point. For instance, we define a function:
modify :: Test -> Test
modify = over (position . x) (*8)
So we can have:
let t1 = Test {_name= "Me", _position = Point {_x = 3, _y = 8}}
then
modify t1
would be:
Test {_name = "Me", _position = Point {_x = 24, _y = 8}}
But, I don't know when and how to use makePrisms in the above example!
In order to understand this, you must understand types, type variables, algebraic data types (sum and product types) and you must also understand typeclasses and the Functor typeclass in particular. If you don't understand these things, bookmark this page, then go off and understand them, possibly with this resource that I helped work on for precisely this purpose, to illustrate and explain these basics: http://happylearnhaskelltutorial.com
So before we get to Prisms, you first need to know what a Lens is.
A Lens is often described as a functional getter/setter, but that's more about the implementation and so forth.
I'd like to try an experiment of description here with you now.
Say I have a page of very small text with some words on it. Now, I hand you a piece of cardboard the same size as that page, only it has hole for a magnifying glass set up to focus on a particular word. That word is in a specific place in that page.
So we have these two things: a page, and a magnifying glass "card" without a magnifying glass... if we put a glass in, it focusses on a particular place on the page. Now someone comes along with another page with different words on it, but in the same layout as the first page.
It's easy to image that you can take that card, put it on the new page and it will focus on the different word in that same place.
As well as a magnifying glass, you also have a special "eraser/printer" glass that when you put it into the card allows you erase and type words over that page.
So to now apply this to Lens, you can see with this example how if we take one piece of data (a page of text), a lens that fits that data (a card with a hole in it that matches the shape of the page) and a function that can "get" or "set" (or maybe other things) (that is, the magnifying glass or the eraser/printer glass, or other types of glasses), well, from this we can view the smaller piece of data (the word) in the larger piece of data (the page) to extract it... or perhaps we can set a different matching piece of data into the spot on that page...
lens :: :: Functor f => (s -> a) -> (s -> b -> t) -> (a -> f b) -> s -> f t
What does this function do? It creates a lens from some functions. Now we have the framework above to understand what a lens is, we can undertsand this function. I say to you that the s variable stands for "state" and it corresponds to the type of the piece of paper that is the context that the lens will focus within. Next I can say the a type variable corresponds to the word on the page that the lens will focus on. What about b and t? They are the transformed a and s values if we decide to change the value of the a, and that change changes its type.
What is the Functor for then? we'll find out in a while. Well, first up let's make a lens to make this practical. So, back to our lens function, its first argument is the "getter" function, the second argument is the "setter" function (hence the types). Then there's one other argument. Well, because Haskell functions are curried that's actually the return type: a function s -> f t. Let's make that lens now.
Let's say we have a list of values [(1,(5,9)), (2,(3,6))] and we'd like to make a lens that focusses on the second value in the second nested tuple. That's silly, though, because you could just use snd . snd right? Yeah, you could, so it's not a great example, but all the better examples are more complex, so bear with me - we'll get to them, and besides, can your snd.snd function also SET, or have a function applied to it? No, I didn't think so! :) (okay okay I know you could use fmap (const val) to set, but can it also change the type? well this line of thought is actually what you end up with Lens with if you continue it to its logical conclusion as Edward Kmett did - that's where the Functor comes in!)
sndOfSndLens = lens (snd.snd) (\(x,(y,z)) newZ -> (x,(y,newZ)))
So what did we get? we got a function of this type sndOfSndLens :: Functor f => (a -> f t2) -> (t, (t1, a)) -> f (t, (t1, t2)).
So let's get our values out: map (view sndOfSnd) [(1,(5,9)), (2,(3,6))] -> [9,6] Nice! That works... let's set new values in: map (set sndOfSnd 2000) [(1,(5,9)), (2,(3,6))] -> [(1,(5,2000)),(2,(3,2000))] okay fine...
If it was just getters or setters, that's boring, but there's also a function called over which will take a lens and a transforming function and run that transformation on the function of the focus of the lens... so let's subtract 10 from each: map (over sndOfSnd (flip (-) 10)) [(1,(5,9)), (2,(3,6))] -> [(1,(5,-1)),(2,(3,-4))] that's cool! well I'll let you read the rest of the lens documentation to understand all the other functions, because they're deep and lenses compose, and you can do all sorts of other things with them, too.
Prism
I promised we'd get to Prism, and look we're here... A Lens is a specific "optic" (while also, sometimes confusingly referring to the entire set of optics in total, too, so watch out for that), and Prism is another optic, thankfully completely specific. If a Lens is an optic that works for focussing on a particular part of a product algebraic data type, then a Prims does the same thing for sum types. That's why we were able to make a lens that talked about pairs ((,)) because they're a product type... that is they combine two types into one. Lens lets you focus on one piece, or a path through those pieces. By the way, our lens we created above can easily be defined by composing the more generic built in lenses: _2 . _2. There are also operator versions of all the lens functions we were talking about. They look pretty crazy, but they have a logic to them. Read up about them!
Prism lets you focus on one path through a sum type. What's a good example? Well, let's say we have think about the Either data type. It's Either a b where it's defined as data Either a b = Left a | Right b. So there's a corresponding prism function that lets us build a Prism the same as our above value. What happens if we use the built in _Left which focusses on the left side of an Either, but we only have a Right 10 value? Let's see... but first, we should let you know that we can't use view any more because it might not work, so we need to use preview which will return a value that might fail (sorry, spoilers!):
preview _Left (Left 10) -> Just 10 and then the Right one? preview _Left (Right 10) -> Nothing. Okay that's sweet.
The set function works fine, because it can fail silently if it doesn't make sense: set _Left 30 (Left 10) -> Left 30. What happens when it doesn't work? set _Right 30 (Left 10) -> Left 10 that's right, nothing.
Cool... hopefully this explains Lenses and Prims. They're two really useful optics. The Lens library is full of them so I encourage you to look at them
What about the original question tho?
The original question was about makeLenses and makePrisms. These are template haskell expressions (that is, they're meta programming / similar to macros, but typed macros), and they let you automatically build your own lenses and/or prisms from your own data types. Hopefully it makes more sense now when you would pick one over the other and how they differ. This will give you at least an inkling into how they're different. To really understand, you should read the documentation and look up all the other functions and optics that are possible.
Welcome to the amazingly cool world of Lenses!
I've come to heavily rely on haskell's type system to avoid bugs and was looking if it could also be used to ensure a (weak?) form of code correctness.
The form of code correctness I have in mind goes as follows:
A function f :: a -> b is correct if f is guaranteed to produce an output of type b for any input of type a. This clearly fails for the well known function head (head:: [a] -> a).
One way I am aware of that the type system fails to guarantee this form of correctness is when code uses error (error :: Char -> a). The error function pretty much overrides the entire type system so I would like to avoid the use of this function unless explicitly intended.
My question is two-fold:
What other functions (or haskell snippets) besides error are exceptions to Haskell's type system?
More importantly, is there a method to forbid the use of such functions within a Haskell module?
Many thanks!
You can write your own functions that never produce a value. Consider the following function:
never :: a -> b
never a = never a
It fails to terminate, so it is considered to be the value _|_ (pronounced bottom). All types in Haskell are actually the sum of the type and this special value.
You can also write a function that is only partially defined, like
undefinedForFalse :: Bool -> Bool
undefinedForFalse True = True
undefinedForFalse False is undefined, which is a special value that is semantically equivalent to _|_ except that the runtime system can stop execution, because it knows it will never finish.
error is also special function that's result is always semantically equivalent to _|_, it tells the runtime system that it can stop execution, knowing it will never finish, along with an informative error message.
Haskell is incapable of proving that a type can never take the value _|_ because it is always possible for a type to take the value _|_. Values that can never be _|_ are called "total". Functions which always produce a value other than _|_ in a finite period of time are called "total functions". Languages that can prove this are called "total languages" or "total functional programming languages". If they can prove this for all types in the language, they are necessarily Turing incomplete.
It isn't possible to prove that any arbitrary function will produce a value in a Turing complete language. You can for some specific functions though, of course. This was covered well by Cirdec, but I would like to point out a couple things with regard to using the type system to guarantee (some level) of correctness.
The relevant topic is parametricity: the fact that given a polymorphic type signature, there is often only a limited set of possible implementations (if we exclude error, undefined and other things like that).
One example of this would be (a -> b) -> a -> b. There's in fact only one possible implementation of this function.
Another example is that given an f from some type A to some type B and a function r :: [a] -> [a], it can be shown that r . map f = map f . r. This is called the "free theorem" for map. Many other polymorphic types also have free theorems.
A (sometimes more useful) result is that if you can prove that a function mapper :: (a -> b) -> F a -> F b obeys the law mapper id = id, it can be shown that mapper f . mapper g = mapper (f . g). Also, this would be the fmap implementation for the type F since those two laws are the Functor laws. This particular "fusion" law can be useful for optimization purposes.
Source: Theorems for free! http://ttic.uchicago.edu/~dreyer/course/papers/wadler.pdf