« first day (1625 days earlier)      last day (338 days later) » 

3:25 AM
. . . . . what is a functor?
ok u know what im just gonna search it up lol
nvm i dont understand it
 
a really shitty way to explain it is it's something you can define fmap for
 
Not quite, you also need to be able to define pure.
 
@UnrelatedString and what does fmap do?
 
isn't pure only for applicative
 
@UnrelatedString Circular definition goes brrrr :P
 
3:27 AM
fmap having the signature Functor f => (a -> b) -> f a -> f b
a list is a functor with fmap = map
and an applicative functor with pure x = [x]
 
but like, i still dont get what a functor even is
 
The difference between applicative functor and just plain functor is <*>, not pure, right?
 
applicative also requires <*> which is uhh
it's both
 
is a functor a function?
 
...it's complicated
 
3:31 AM
Is it something that takes a type and returns a new type? Like how [a] is the type "list that contains items of type a"?
 
@DLosc huh, dont functions already do that (take in some value and return another), or am i missing something
 
i'm hazy on the precise terminology but all functors do that (have kind * -> *) but not everything that does that is a functor
a trivial and uninteresting example is the hugeass tuples where they just didn't bother to give them Functor instances but totally could have
 
@AidenChow I'm not sure if I'm looking at it the way Haskell does, but at least in my mind I'm distinguishing between doing something with a value of a given type, and doing something with the type itself
 
[a] isn't a functor. It's the return of applying the list functor to the type a.
 
@Nitrodon Yeah, that's what I meant
 
3:34 AM
ok so functor = type ?????
so confused here
 
Functor is to type what function is to value
(right?)
 
A functor (e.g., list) takes a type (e.g. integer) and returns another type (e.g., list of integers).
 
@DLosc took me a while to realize that that was an analogy lol
couldnt understand what you were saying for a split second :P
 
a functor is a type of kind * -> * for which there's a definition of fmap (i.e. a Functor instance)
let me whip up a redefinition of the identity functor rq
 
3:36 AM
@AidenChow I considered using : :: : syntax but thought the English words might be more understandable. Glad you got there eventually. :)
 
Does Haskell have the identity functor?
 
it's in a module somewhere
99% sure it's called Identity and it's probably in Data.Functor
but reimplementing it is Instructive™
 
so, i kinda get what a functor is, but how would i actually define a functor? similar to a function?
 
Anyway, in order for something of kind * -> * to be a functor, it has to have the fmap function.
and this function must satisfy the laws fmap id x = x and (fmap f) (fmap g x) = fmap (f . g) x
 
@Nitrodon Ohhh--is Maybe a functor?
 
3:40 AM
It is. It's even a monad.
 
still dont understand what fmap is
 
is it kinda like map but for functors and types instead of functions and values?
 
and apparently I was mistaken earlier and functors don't require pure. Does this mean that there's an empty functor?
 
Either is also a functor
 
3:41 AM
@Nitrodon Okay, that's helpful. Maybe makes sense to me because I've used the equivalent in Scala.
 
@Nitrodon i vaguely remember a question on so about this and i thiiiiiink the answer was yes
 
Well, list is a functor, and its implementation of fmap is map.
 
There's also the Maybe functor that DLosc mentioned. Maybe a is defined as Nothing | Just a.
and then fmap on Maybe is defined by fmap f Nothing = Nothing; fmap f (Just x) = Just (f x)
 
@AidenChow Okay, I think I understand it now, so let's try this explanation. Say I define a functor called Box. I can put any type into a Box: I can have a Box containing an Int, or a Box containing a String, or whatever.
Now say x is a Box containing the Int 42, and I want to add 1 to it. I can't just add 1 to x directly, because x isn't an Int; it's a Box of Int. I need to add 1 to the Int inside the Box, and then return a new Box of Int containing that result.
That's what fmap does. It applies the function ("plus 1," in this case) to whatever's inside the Box, and returns a new Box containing the result.
 
3:50 AM
what's critical is you can do that with any function from the type "inside the box" to some other type, whatever the type inside the box is
 
You can also fmap a function like show, which converts its input into a string.
 
So if the function was "convert to a string and concatenate !," I could fmap that to the Box of 42 and get a Box of "42!" back
 
or the "put it in a box" function, so you'd have a Box of a Box of 42.
(and since Box is actually a monad, you can convert that Box of Box of 42 back into a Box of 42)
 
What does monad mean? I think I might finally be in a position to understand the answer, lol
 
Looks like we're going down the hard route, and yet we haven't touched some easier and good-for-golf stuff like list comprehension
 
3:56 AM
Is there a Haskell chat room? We could take the deeper stuff there.
 
It's a functor with return :: a -> m a and >>= :: m a -> (a -> m b) -> m b.
 
There used to be Of Monads and Men but it's been frozen for 2 years straight
 
Equivalently, you can say it has return and a "flatten" function of type m m a -> m a.
 
Jo King has unfrozen this room.
17
Q: Tips for restricted source in Haskell

Wheat WizardI tested the waters on this sort of question with python, but now I get to the real question I want to ask. restricted-source challenges are uniquely rewarding in Haskell because of Haskell's strict rule set. Type coercion which is the bread and butter for other languages in these sort of challe...

15
Q: How to golf a fork in Haskell?

userI'm trying to make a pointfree function f that can act like APL's dyadic forks/Husk's §, so f g h i a b equals g (h a) (i b), where g is a binary function, h and i are unary functions, and a and b are integers (I'm only dealing with integers and not other types right now). I converted the functio...

6
A: Tips for golfing in Haskell

xnorCheap divisors The usual way to get the divisors (factors) of n is: [d|d<-[1..n],mod n d<1] For example, n=6 gives [1,2,3,6]. But, if you're OK with divisors repeating out of order, you can just do: gcd n<$>[1..n] For n=6, this gives [1,2,3,2,1,6]. The code is effectively [gcd k n|k<-[1..n]], ...

5
A: Tips for golfing in Haskell

xnorAvoid sorting Haskell doesn't have a built-in sorting in Prelude. It can be accessed with an import: import Data.List sort This also gives you access to functions like sortOn and sortBy, as well as other functions in Data.List. But, many times you don't need the full power of sorting and can ma...

4
A: Tips for golfing in Haskell

xnorBinary op on two-element list You can apply a binary operation to a two-element list like: foldr1(-)[5,3] to get 5-3, or 2. Note that this operator must output the same type as the input, that is be a -> a -> a. So, foldr1(==)[5,3] doesn't typecheck but foldr1 mod[5,3] does. You can think of thi...

5
A: Tips for golfing in Haskell

LynnThe function 0^x This maps positive integers to 0 and zero to 1. So, it acts a little bit like !x in C-like languages. It crashes for negative x; in this case you can write 0^x^2, which parses as 0^(x^2). This is not technically specific to Haskell, but Haskell is quite strict about converting be...

 
oh wow you were holding those in for a while bot
6 messages moved from The Nineteenth Byte
 
4:05 AM
@Nitrodon ... Nope, I don't understand that. Can you say that again but with more English? ;P
 
For instance, you can flatten a list of lists of integers into just a list of integers.
 
63 messages moved from The Nineteenth Byte
 
Maybe is also a monad.
>>= :: Maybe a -> (a -> Maybe b) -> Maybe b would be defined as Nothing >>= f = Nothing; Just x >>= f = f x
or at least I think that's what >>= is. All these weird combinations of punctuation can get confusing.
 
@Nitrodon also worth noting that this "flatten" function is join (in Control.Monad) and is just (>>=id)
 
I'm aware that it's (>>=id), but I'm not familiar enough with Haskell to know that it's called join.
 
4:12 AM
np
 
Is List a monad?
 
yes
 
B/c I'm having trouble understanding what [1,2,3] >>= id would return
 
and you can go back to >>= from join with flip((join.).fmap)
@DLosc it doesn't
since Ints aren't a monad
 
Ah, okay
 
4:13 AM
because Int isn't [a] for some a
 
So >>= requires its argument to be a monad containing a monad?
 
unless you have some Monad m, Num m a but let's not worry about literals being polymorphic
yep
specifically the same monad
 
>>=id does, yes.
 
(>>=) :: Monad m => m a -> (a -> m b) -> m b
er yeah >>=id specifically
 
[1,2,3] >>= (\x -> [x, 2*x]) is just fine.
 
4:14 AM
whats this chat room
 
since the a -> m b is a -> a it has to be m b -> m b
 
Right, okay
 
I've been wondering off and on for a bit: is join . join = join . fmap join?
 
@UnrelatedString So let me try to rephrase in words so I can make sure I understand:
 
and how would one prove that with the monad laws?
 
4:16 AM
@Nitrodon ...probably
 
Suppose m is some kind of Monad. Then >>= is a function that takes an (m containing as), and a function from as to (m containing bs)s, and returns an (m containing bs).
 
yes
 
what does >>= do?
 
4:33 AM
@AidenChow Partial answer: if you give it a List of Somethings and a function that transforms each Something into a List of SomethingElses, it applies the function to each element of the list and then joins the resulting list of lists into one flat list (somewhat like flatMap in JavaScript).
It also works on things that aren't Lists, but for that you'll need to read through the preceding discussion about monads.
 
@DLosc Indeed. Notice that a Haskell string is just a list of characters.
 
@Nitrodon Right, which is why I picked that example; I was trying to think of a non-contrived function Int -> [a] and then I realized that show had that signature.
BTW, why is it that specific types use InitialCaps but these abstract types (?) in function signatures use lowercase?
 
to make that distinction
 
what does show do?
 
since a type variable is very distinctly different from an actual type in that kind of context
there's a reason ScopedTypeVariables is an extension
@AidenChow string representations
 
4:37 AM
@UnrelatedString Makes sense... I kinda wish there were also a distinction between type variables and regular variables, tho
 
specifically, for any type implementing Show, you can get a string from showing it
@DLosc it's not really a problem since types and values don't really exist in the same places syntactically
 
show is also used internally by print.
 
note that you can define algebraic data types where their constructors look the same as the type itself and where they don't
it just doesn't matter since the constructors and the type itself can't occur in the same places
 
@UnrelatedString Well, sure, it's not a problem for the compiler or for fluent Haskellers. But I am neither of those things. ;P
 
(and constructors have to be distinguished from normal functions syntactically so you can pattern-match them)
lol
 
 
11 hours later…
4:09 PM
What about infix constructors?
How do you distinguish those from normal infix functions?
 
 
7 hours later…
11:23 PM
@user I think all infix constructors start with a colon.
 
11:56 PM
Ah, interesting
 

« first day (1625 days earlier)      last day (338 days later) »