Logs: freenode/#haskell
| 2021-03-29 08:45:04 | × | solvr quits (57e3c46d@87.227.196.109) (Quit: Connection closed) |
| 2021-03-29 08:46:28 | → | pupuupup_ joins (~pupuupup@ppp-124-122-192-176.revip2.asianet.co.th) |
| 2021-03-29 08:46:40 | → | ddellacosta joins (ddellacost@gateway/vpn/mullvad/ddellacosta) |
| 2021-03-29 08:48:21 | × | drbean_ quits (~drbean@TC210-63-209-15.static.apol.com.tw) (Quit: ZNC 1.8.2+cygwin2 - https://znc.in) |
| 2021-03-29 08:48:52 | × | ixlun quits (~matthew@109.249.184.133) (Read error: Connection reset by peer) |
| 2021-03-29 08:48:53 | Guest42457 | is now known as SIben |
| 2021-03-29 08:49:54 | → | benkolera joins (uid285671@gateway/web/irccloud.com/x-eheuohrapvmfijla) |
| 2021-03-29 08:50:46 | × | pupuupup_ quits (~pupuupup@ppp-124-122-192-176.revip2.asianet.co.th) (Ping timeout: 240 seconds) |
| 2021-03-29 08:51:56 | × | ddellacosta quits (ddellacost@gateway/vpn/mullvad/ddellacosta) (Ping timeout: 268 seconds) |
| 2021-03-29 08:52:33 | × | stree quits (~stree@68.36.8.116) (Ping timeout: 268 seconds) |
| 2021-03-29 08:58:17 | → | michalz joins (~user@185.246.204.46) |
| 2021-03-29 09:01:50 | → | enoq joins (~textual@194-208-146-143.lampert.tv) |
| 2021-03-29 09:02:46 | × | lawid quits (~quassel@dslb-178-005-066-219.178.005.pools.vodafone-ip.de) (Ping timeout: 240 seconds) |
| 2021-03-29 09:03:33 | → | lawid joins (~quassel@dslb-178-005-075-139.178.005.pools.vodafone-ip.de) |
| 2021-03-29 09:05:21 | → | stree joins (~stree@68.36.8.116) |
| 2021-03-29 09:06:18 | → | Iryon joins (~Iryon@2a02:a31a:a045:3500:5420:2237:4aee:26f2) |
| 2021-03-29 09:08:07 | → | SaitamaPlus joins (uid272474@gateway/web/irccloud.com/x-gljisqtsvqcmgfbx) |
| 2021-03-29 09:16:12 | × | MarcelineVQ quits (~anja@198.254.208.159) (Read error: Connection reset by peer) |
| 2021-03-29 09:17:32 | → | MarcelineVQ joins (~anja@198.254.208.159) |
| 2021-03-29 09:17:46 | → | pupuupup_ joins (~pupuupup@ppp-124-122-192-176.revip2.asianet.co.th) |
| 2021-03-29 09:20:08 | → | gaff joins (~user@49.207.222.255) |
| 2021-03-29 09:21:34 | <gaff> | is there a way to turn data Line a = Line a | Foo (a, a) | Empty into a monad instance |
| 2021-03-29 09:21:37 | <gaff> | ? |
| 2021-03-29 09:22:30 | × | pupuupup_ quits (~pupuupup@ppp-124-122-192-176.revip2.asianet.co.th) (Ping timeout: 265 seconds) |
| 2021-03-29 09:23:07 | <merijn> | I don't think so? |
| 2021-03-29 09:23:14 | <gaff> | i see |
| 2021-03-29 09:23:24 | <merijn> | gaff: Consider the type of >>= |
| 2021-03-29 09:23:30 | <merijn> | :t (>>=) |
| 2021-03-29 09:23:31 | <lambdabot> | Monad m => m a -> (a -> m b) -> m b |
| 2021-03-29 09:23:39 | <gaff> | yes |
| 2021-03-29 09:23:50 | <merijn> | So you need to take a function "a -> Line b" and return "Line b" |
| 2021-03-29 09:24:00 | <gaff> | yes |
| 2021-03-29 09:24:14 | → | ddellacosta joins (ddellacost@gateway/vpn/mullvad/ddellacosta) |
| 2021-03-29 09:24:22 | <merijn> | What would that look like when the input is "Foo"? You have two a's, you can run the function twice, but then you have *two* "Line b" values that need to be turned into one "Line b" to typecheck |
| 2021-03-29 09:24:30 | → | pupuupup joins (~pupuupup@ppp-124-122-192-176.revip2.asianet.co.th) |
| 2021-03-29 09:24:33 | <merijn> | I don't think you can write a law abiding instance that does that |
| 2021-03-29 09:24:44 | <gaff> | the types will not match up |
| 2021-03-29 09:25:17 | <gaff> | also, you can not define a sensible return |
| 2021-03-29 09:25:38 | <merijn> | "return = Line" seems sensible enough |
| 2021-03-29 09:25:52 | <gaff> | no, it isn't |
| 2021-03-29 09:26:02 | <gaff> | how will you define return |
| 2021-03-29 09:26:04 | <gaff> | ? |
| 2021-03-29 09:26:30 | <gaff> | why is that sensible? |
| 2021-03-29 09:26:53 | <merijn> | Why not? |
| 2021-03-29 09:27:47 | <merijn> | Just looking at the "shape" of your datatype it seems reasonable enough |
| 2021-03-29 09:28:02 | <gaff> | return (a, b) = ? |
| 2021-03-29 09:28:32 | <gaff> | you have 2 cases: return (a, b), return a |
| 2021-03-29 09:28:56 | × | ddellacosta quits (ddellacost@gateway/vpn/mullvad/ddellacosta) (Ping timeout: 268 seconds) |
| 2021-03-29 09:29:10 | <opqdonut> | I could see a fun applicative instance for Line though: Line f <*> Line x = Line (f x); Line f <*> Foo (x, y) = Foo (f x, f y); Foo (f, g) <*> Line x = Foo (f x, g x); Foo (f, g) <*> Foo (x, y) = Foo (f x, g y); _ <*>_ = Empty |
| 2021-03-29 09:29:40 | <opqdonut> | gaff: there is no requirement to be able to produce all kinds of values in your type using "return" |
| 2021-03-29 09:29:54 | <gaff> | ok |
| 2021-03-29 09:29:54 | <opqdonut> | gaff: e.g. for lists, return x = [x]. There is no way to produce [1,2,3] using return. |
| 2021-03-29 09:29:58 | × | azure2 quits (~azure@180.247.95.50) (Ping timeout: 260 seconds) |
| 2021-03-29 09:30:13 | <opqdonut> | similarly for Maybe, return x = Just x. There is no way to produce Nothing using return. |
| 2021-03-29 09:30:24 | <gaff> | so why is return = Line sensible? |
| 2021-03-29 09:30:56 | <gaff> | why not return (a, b) = Foo (a, b)? |
| 2021-03-29 09:30:56 | <opqdonut> | the types match, and it works with e.g. the Applicative instance I just wrote out |
| 2021-03-29 09:31:04 | <opqdonut> | gaff: that wouldn't type |
| 2021-03-29 09:31:24 | <opqdonut> | it needs to be return :: a -> Line a. Your return would be (a,a) -> Line a |
| 2021-03-29 09:31:24 | → | azure2 joins (~azure@180.247.95.50) |
| 2021-03-29 09:31:57 | <gaff> | ah, i see |
| 2021-03-29 09:31:59 | <opqdonut> | return x = Foo (x,x) would type, as would return x = Empty |
| 2021-03-29 09:32:22 | <gaff> | got it |
| 2021-03-29 09:34:26 | <gaff> | so my question is, if we have f :: Line -> IO [Line], and g :: IO (), how can you extract values from Line within a do construact in g? |
| 2021-03-29 09:34:42 | → | Aquazi joins (uid312403@gateway/web/irccloud.com/x-qybeoxhtmvdqtlff) |
| 2021-03-29 09:34:46 | <gaff> | given that Line is not a monad |
| 2021-03-29 09:34:55 | <opqdonut> | you do it |
| 2021-03-29 09:36:04 | <opqdonut> | something like: g = do ...; result <- f line; let foo = map something result; let final = foldr quux xyzzy foo; print final |
| 2021-03-29 09:36:39 | <opqdonut> | IO is the monad here, Line doesn't need to be a monad |
| 2021-03-29 09:36:46 | <gaff> | yes |
| 2021-03-29 09:37:17 | → | mouseghost joins (~draco@87-206-9-185.dynamic.chello.pl) |
| 2021-03-29 09:37:18 | × | mouseghost quits (~draco@87-206-9-185.dynamic.chello.pl) (Changing host) |
| 2021-03-29 09:37:18 | → | mouseghost joins (~draco@wikipedia/desperek) |
| 2021-03-29 09:38:40 | <gaff> | ok, i have to think about that |
| 2021-03-29 09:39:07 | <gaff> | so you extract the values using pattern matching? |
| 2021-03-29 09:40:16 | <opqdonut> | for example, yes |
| 2021-03-29 09:47:30 | <gaff> | so suppose you have to call a function, say, p :: (Int, Int) -> Int in g :: IO (), where p 's tuple comes from Foo (x, y). when you pattern match an item in result, you have 2 cases: Foo (x, y) -> p (x, y). but what would you do with the other case, Line a -> ? |
| 2021-03-29 09:47:58 | × | pupuupup quits (~pupuupup@ppp-124-122-192-176.revip2.asianet.co.th) (Ping timeout: 240 seconds) |
| 2021-03-29 09:49:31 | → | pupuupup joins (~pupuupup@ppp-124-122-192-176.revip2.asianet.co.th) |
| 2021-03-29 09:52:31 | <opqdonut> | gaff: it depends on what you want the code to do |
| 2021-03-29 09:52:47 | <opqdonut> | `Line a -> 0` would type check |
| 2021-03-29 09:52:57 | <opqdonut> | or you can just leave the case unhandled and get an error at runtime :) |
| 2021-03-29 09:53:08 | <gaff> | ah, i see |
| 2021-03-29 09:53:51 | <ski> | hm, it might be possible to make a (lawful) `Monad' instance for `Line' .. |
| 2021-03-29 09:53:59 | <gaff> | it is cruffy stuff. i imagine people face these sort of situations often. and they have to revert to runtime checks. |
| 2021-03-29 09:54:09 | <opqdonut> | ski: just ignore the second component of Foo? |
| 2021-03-29 09:54:17 | <ski> | no |
| 2021-03-29 09:54:19 | <opqdonut> | ok |
| 2021-03-29 09:54:27 | <ski> | i don't think that would work |
| 2021-03-29 09:55:05 | <ski> | `join (Foo (Foo (a,b),Foo (c,d)) = Foo (a,d)' sounds reasonable, i think. however, there's more cases to consider |
| 2021-03-29 09:55:20 | × | MarcelineVQ quits (~anja@198.254.208.159) (Ping timeout: 252 seconds) |
| 2021-03-29 09:55:52 | <opqdonut> | (hmm yes m >>= return === m doesn't hold if you ignore the other component) |
| 2021-03-29 09:56:07 | <ski> | i think if we treat `Line a' as if it was `Foo (a,a)', then that could work. and if there's any `Empty', then the overall result is `Empty' |
| 2021-03-29 09:56:18 | <opqdonut> | mmh |
| 2021-03-29 09:56:38 | <gaff> | yes |
| 2021-03-29 09:56:43 | <ski> | would need to check all cases for associativity to make sure, though. but it looks like it might work, on first thought |
| 2021-03-29 09:56:56 | <ski> | however, it's likely that this is not what gaff really needed |
| 2021-03-29 09:57:47 | → | MarcelineVQ joins (~anja@198.254.208.159) |
| 2021-03-29 09:59:05 | <ski> | i guess this may be like `MaybeT Pair' or something, hm |
| 2021-03-29 09:59:11 | <gaff> | ski: basically, i outlined the need a few minutes back. i want to extract (a, b) and pass it to a function p, where p :: (Int, Int) -> Int, and this code needs to be within a function :: IO (). |
All times are in UTC.