c_wraith 2017-03-02 04:45:14
nitrix: hey, you're right!
c_wraith 2017-03-02 04:45:23
kubunto: fmap isn't a good choice for that
johnw 2017-03-02 04:45:26
kubunto: that isn't what Functor does; but lenses can do that
c_wraith 2017-03-02 04:45:35
kubunto: since fmap requires being able to change the type arbitrarily
johnw 2017-03-02 04:45:40
also, MonoFunctor could do that
nitrix 2017-03-02 04:46:06
kubunto: What you're describing isn't a Functor. The type of what is changing has to be parametric.
kubunto 2017-03-02 04:46:30
should mention the larger goal of this is to learn more about monads and functors
kubunto 2017-03-02 04:47:30
if a graph data structure doesnt play well with functors then i would love to know what would
aweinstock 2017-03-02 04:47:47
does unsafeDupablePerformIO have any proof obligations/invariants other than thread-safety/purity?
johnw 2017-03-02 04:50:43
kubunto: graphs over arbitrary node types play very well with functors
nitrix 2017-03-02 04:51:54
kubunto: I recommend you to implement the functor instance of the Maybe type.
nitrix 2017-03-02 04:52:13
kubunto: data MyMaybe a = Just a | Nothing
nitrix 2017-03-02 04:52:29
Oh I guess you'd need *MyJust *MyNothing
nitrix 2017-03-02 04:53:56
kubunto: Name it something different from the existing Maybe type and its constructors and see if you can come up with the functor implementation.
kubunto 2017-03-02 04:54:30
nitrix: where is pattern matching in relation to functors?
nitrix 2017-03-02 04:54:42
kubunto: It's probably easier to implement some of these first to build some intuition, then look into what is and isn't a functor.
nitrix 2017-03-02 04:56:22
kubunto: Well, for an algebraic data type to be useful, it's going to have a constructor. And working with that data type (like defining instances that manipulates it) will require you to unwrap/rewrap something at some point, to make it of the type MyMaybe.
nitrix 2017-03-02 04:56:49
kubunto: e.g. 42 :: Int, MyJust 42 :: MyMaybe Int.
kubunto 2017-03-02 04:57:46
nitrix: i played with that concept in tree form the other day
nitrix 2017-03-02 04:57:46
kubunto: You can see the difference in type here, which is caused by us constructing a value of type `MyMaybe Int` using the MyJust constructor.
kubunto 2017-03-02 04:57:46
using a pattern matcher to unwrap values
nitrix 2017-03-02 04:58:09
kubunto: Same thing happens in reverse when you're deconstructing (pattern matching) the data type to work on it.
nitrix 2017-03-02 04:58:40
kubunto: But to answer your question, it's not a requirement of *functors*, just an Haskell data type thing.
nitrix 2017-03-02 04:59:08
kubunto: Here's an easier one for you: data Simple a = MkSimple a
nitrix 2017-03-02 05:00:01
kubunto: Can you figure out how to implement fmap for this :) ?
kubunto 2017-03-02 05:00:26
fmap would unwrap and re wrap?
nitrix 2017-03-02 05:01:33
Yeah, you'd have to unwrap that Simple type, apply the transformation, then rewrap it.
nitrix 2017-03-02 05:02:09
Effectively transforming what's "inside" of Simple.
merijn 2017-03-02 05:02:39
johnw: And here I am representing my graphs as just arrays of numbers :p
kubunto 2017-03-02 05:03:04
nitrix: i could figure a pattern matching function yes
nitrix 2017-03-02 05:03:41
kubunto: Try it :P Then we can try more complicated ones or see why some types can be functors and others cannot.
nitrix 2017-03-02 05:10:26
kubunto: You can compare you answer with mine (http://lpaste.net/353130)
kubunto 2017-03-02 05:10:33
nitrix: i made curried functor for simple
nitrix 2017-03-02 05:10:46
A curried functor?
kubunto 2017-03-02 05:11:16
the function was fsimple f a
kubunto 2017-03-02 05:11:50
used a pattern match to unwrap it and returned it in the same data structure
nitrix 2017-03-02 05:12:06
You can just paste your line.
kubunto 2017-03-02 05:12:38
MkSimple a -> MkSimple $ f a
nitrix 2017-03-02 05:13:40
That doesn't seems quite right. Where's your function definition? Where does `f` comes from? If it's a lambda, the syntax isn't correct either.
nitrix 2017-03-02 05:14:41
fmap f (MkSimple x) = MkSimple (f a)
kubunto 2017-03-02 05:14:48
http://lpaste.net/353131
nitrix 2017-03-02 05:14:51
fmap f (MkSimple x) = MkSimple (f x)
nitrix 2017-03-02 05:15:12
kubunto: There you go :D
kubunto 2017-03-02 05:15:29
what is this instance thing?
nitrix 2017-03-02 05:16:19
kubunto: Two details here. (1) You didn't define the functor instance, you created a completely new function named fsimple, when you're supposed to be implementing the `fmap` function of the `Functor` type class, via in instance for your Simple type.
nitrix 2017-03-02 05:17:01
(2) That means getting rid of the extension DeriveFunctor and the `deriving` keyword, they aren't doing anything for you there and probably best to ignore until you're comfortable with functors.
nitrix 2017-03-02 05:18:30
kubunto: I did like the creative use of `case of` though for the pattern matching, but you can achieve the same by pattern matching the arguments of your function definition directly (left hand side of = ).
nitrix 2017-03-02 05:21:06
Your solution hints me you need a slightly better intuitions of type classes. Type classes are a regroupment of types that have a property in common. Usually we leverage that property by providing a common interface for such types (so, a polymorphic function that works for any of the types that defines an instance for that type class).
nitrix 2017-03-02 05:21:22
kubunto: Are you familiar with Java interfaces, possibly?
kubunto 2017-03-02 05:21:33
that comes from scala
nitrix 2017-03-02 05:22:16
What "comes" ?
kubunto 2017-03-02 05:22:26
nitrix: i know pattern matching because of familiarity with scala
nitrix 2017-03-02 05:22:31
Gotcha :P
nitrix 2017-03-02 05:23:54
kubunto: In other words, for the user to be able to use `fmap` on a value of type `Simple`, the author of `Simple` has to define the instance `Functor Simple`.
ongy 2017-03-02 05:24:36
I have a withFile and us hGetContents in it, iirc that's dangerous because of lazy-IO. I want to return an IO Int, what's the best way to force the evaluation of the Int so I know all IO has been done before withFile returns?
glguy 2017-03-02 05:25:51
ongy: You can use Control.Exception.evaluate on the resulting Int inside the withFile.
merijn 2017-03-02 05:26:48
ongy: Depends, which hGetContents?
ongy 2017-03-02 05:27:12
glguy: ah looks good to me. merijn Prelude.hGetContents (for now)
merijn 2017-03-02 05:27:44
ongy: hGetContents is only lazy IO for String and lazy Text/BS
merijn 2017-03-02 05:27:46
ongy: strict Text and BS use a strict hGetContents
nitrix 2017-03-02 05:27:54
kubunto: Maybe you want to give it another try? You seem like you're pretty close for it all to click :)
ongy 2017-03-02 05:28:08
merijn: oh, good to know
ongy 2017-03-02 05:28:26
and makes a lot of sense. But I will use String for now
kubunto 2017-03-02 05:29:13
http://lpaste.net/353132 nitrix
kubunto 2017-03-02 05:29:39
is fmap supposed to loop over a collection as well?
nitrix 2017-03-02 05:29:48
kubunto: Assuming data Foo a = Baz | Bar a ?
kubunto 2017-03-02 05:29:54
nitrix: yup
nitrix 2017-03-02 05:30:05
kubunto: If that's what you want it to do, sure. The functor instance of [] does this.
nitrix 2017-03-02 05:30:12
> fmap (+1) [1,3,5]
lambdabot 2017-03-02 05:30:16
[2,4,6]
kubunto 2017-03-02 05:31:06
nitrix: i tried fmap (^2) [Bar 4, Baz] with no luck
nitrix 2017-03-02 05:31:24
@let data Foo a = Baz | Bar a
kubunto 2017-03-02 05:31:26
would have expected [Bar 16, Baz] back
lambdabot 2017-03-02 05:31:27
Defined.
nitrix 2017-03-02 05:31:50
> (fmap . fmap) (^2) [Bar 4, Baz]
lambdabot 2017-03-02 05:31:54
error:
lambdabot 2017-03-02 05:31:54
• Could not deduce (Functor Foo) arising from a use of 'fmap'
lambdabot 2017-03-02 05:31:54
from the context: Num b
nitrix 2017-03-02 05:32:02
Oh I forgot the functor instance.
nitrix 2017-03-02 05:32:25
kubunto: You need two fmaps. There are two functors. The [] functor and then the Foo functor.
nitrix 2017-03-02 05:32:29
They're nested.
kubunto 2017-03-02 05:32:51
ah
kubunto 2017-03-02 05:36:21
nitrix: i am not seeing how to get it recursive
kubunto 2017-03-02 05:36:30
like in a tree traversal
nitrix 2017-03-02 05:37:08
kubunto: It can only be recursive for its own type (itself), if that's what you mean. Which is what recursive is.
nitrix 2017-03-02 05:37:18
In the [] and Foo example, they aren't recursive, they're simply nested.
nitrix 2017-03-02 05:38:06
kubunto: Try a binary tree first, maybe? data Tree a = End | Node (Tree a) a (Tree a) ?
kubunto 2017-03-02 05:38:24
nitrix: i was doing data Tree a = Leaf a | Branch a (Maybe (Tree a)) (Maybe (Tree a))
kubunto 2017-03-02 05:38:30
without the maybes
Onemorenickname 2017-03-02 05:38:48
hi
Onemorenickname 2017-03-02 05:38:53
i guess i kinda managed my grammar problem
nitrix 2017-03-02 05:39:06
kubunto: So you had what I just wrote, minor your leaves have a value in your example. You don't really need it but it's up to you.
Onemorenickname 2017-03-02 05:39:25
for those interested, all my grammar have now a context, and such, different grammars in different contexts can have the same name
Onemorenickname 2017-03-02 05:39:27
yay
Onemorenickname 2017-03-02 05:40:02
i lose some static checking, still, i have my most desired property
nitrix 2017-03-02 05:40:05
kubunto: data Tree a = End | Node (Tree a) a (Tree a)
nitrix 2017-03-02 05:40:21
kubunto: fmap f End = End
nitrix 2017-03-02 05:40:43
kubunto: fmap f (Node leftTree value rightTree) = ...
nitrix 2017-03-02 05:41:00
kubunto: Does that helps?
nitrix 2017-03-02 05:41:56
You should be able to figure out how to transform the current value, as well as continue the transformation on the left side and right side of the tree as well.
kubunto 2017-03-02 05:43:35
nitrix: i am seeing if i can do it with 2 types
kubunto 2017-03-02 05:43:52
Tree a b
nitrix 2017-03-02 05:44:06
kubunto: You'll have a hard time.
nitrix 2017-03-02 05:44:20
kubunto: `Tree a b` has the wrong kind to be a functor.
nitrix 2017-03-02 05:44:45
kubunto: Given `Tree a b`, only (Tree a) can be a functor.