Newest at the top
2024-09-30 18:25:58 +0200 | <Inst> | https://hackage.haskell.org/package/base-4.20.0.1/docs/Type-Reflection.html#t:TypeRep |
2024-09-30 18:25:57 +0200 | <Inst> | tomsmeding: I guess what I'm really looking for with all this match partially-applied constructor nonsense is |
2024-09-30 18:24:25 +0200 | <tomsmeding> | monochrom: final sentence: "more kind of bugs" -> "more kinds of bugs" |
2024-09-30 18:23:35 +0200 | <tomsmeding> | monochrom: thanks, I learned about parametricity today! |
2024-09-30 18:22:19 +0200 | <tomsmeding> | ah, and also what I said |
2024-09-30 18:21:56 +0200 | <tomsmeding> | sorry that's what I meant |
2024-09-30 18:21:50 +0200 | <yahb2> | \n -> if n == 0 then Bar 42 else Baz 100 ; :: (Eq a, Num a) => a -> Foo |
2024-09-30 18:21:50 +0200 | <tomsmeding> | % :t \n -> if n == 0 then Bar 42 else Baz 100 |
2024-09-30 18:21:48 +0200 | <yahb2> | <no output> |
2024-09-30 18:21:48 +0200 | <tomsmeding> | % data Foo = Bar Int | Baz Int |
2024-09-30 18:21:42 +0200 | <yahb2> | <interactive>:1:38: error: [GHC-39999] ; • Could not deduce ‘Num Char’ arising from the literal ‘100’ ; from the context: (Eq a, Num a) ; bound by the inferred type of it :: (Eq a... |
2024-09-30 18:21:42 +0200 | <tomsmeding> | % :t \n -> if n == 0 then Bar 42 else Baz 100 |
2024-09-30 18:21:32 +0200 | <yahb2> | <no output> |
2024-09-30 18:21:31 +0200 | <tomsmeding> | % data Foo = Bar Int | Baz Char |
2024-09-30 18:21:25 +0200 | <ski> | __monty__ : well, if you do, you can use `(<*>) = liftA2 ($)' |
2024-09-30 18:21:06 +0200 | <Inst> | the if expression isn't well-typed |
2024-09-30 18:20:31 +0200 | <__monty__> | ski: Haven't written enough liftA2s to have an opinion TBH. |
2024-09-30 18:20:24 +0200 | <tomsmeding> | and that ain't going to work |
2024-09-30 18:20:22 +0200 | <tomsmeding> | because if you'd have `data Foo = Bar Int | Baz Int`, then perhaps `f :: (Int -> Foo) -> _`, but from that type I should also be able to pass `\n -> if n == 0 then Bar 42 else Baz 100` to f |
2024-09-30 18:19:40 +0200 | andrewboltachev | (~andrey@178.141.123.3) (Quit: Leaving.) |
2024-09-30 18:19:25 +0200 | <tomsmeding> | but also the eta-expansion argument that I gave which tells you that even if you'd have a data type for which the types do line up, we still don't want this |
2024-09-30 18:19:24 +0200 | <Inst> | f Left Bar works |
2024-09-30 18:19:09 +0200 | <Inst> | That said: |
2024-09-30 18:19:03 +0200 | <Inst> | f Bar = ...; f Baz = ...; f :: ??? |
2024-09-30 18:18:59 +0200 | <tomsmeding> | that syntax is indeed free, but typing indeed presents a problem |
2024-09-30 18:18:39 +0200 | <tomsmeding> | `f Bar = ...`? |
2024-09-30 18:18:33 +0200 | <Inst> | I mean data Foo = Bar Int | Baz Char |
2024-09-30 18:18:20 +0200 | <tomsmeding> | `f Left = ...`? |
2024-09-30 18:18:11 +0200 | <Inst> | i pointed out there's a possible syntax but it makes no sense in a statically typed language |
2024-09-30 18:17:53 +0200 | <Inst> | you asked "what would you expect the syntax to even be" |
2024-09-30 18:17:34 +0200 | <tomsmeding> | there's nothing "partially applied" going on here |
2024-09-30 18:17:28 +0200 | <tomsmeding> | the {} syntax is just from record syntax; it just allows you to elide the actual fields |
2024-09-30 18:16:55 +0200 | <Inst> | Bar :: Int -> Foo; Baz :: Char -> Foo |
2024-09-30 18:16:38 +0200 | <Inst> | what is the type of your function? |
2024-09-30 18:16:32 +0200 | <c_wraith> | You'd use positional match syntax if you want to reconsider your definition when the type changes. You'd use record match syntax when you want to ignore changes to the definition. |
2024-09-30 18:16:29 +0200 | <Inst> | if you're trying to top level pattern match on a constructor from Foo |
2024-09-30 18:16:26 +0200 | raehik | (~raehik@rdng-25-b2-v4wan-169990-cust1344.vm39.cable.virginm.net) (Ping timeout: 252 seconds) |
2024-09-30 18:15:45 +0200 | <c_wraith> | It mostly depends on what kinds of changes you're expecting. Like, you'd never expect Either to change its definition, so it really doesn't matter. But if you have some domain type that might frequently change during development it can matter. |
2024-09-30 18:14:21 +0200 | <tomsmeding> | still not sure where the inconsistent types come from or what you really mean :p |
2024-09-30 18:14:10 +0200 | gmg | (~user@user/gehmehgeh) (Quit: Leaving) |
2024-09-30 18:14:00 +0200 | <tomsmeding> | sometimes, yes |
2024-09-30 18:13:47 +0200 | <c_wraith> | sometimes. |
2024-09-30 18:13:42 +0200 | <Inst> | c_wraith: wait, do people actually use that syntax? |
2024-09-30 18:13:34 +0200 | merijn | (~merijn@77.242.116.146) (Ping timeout: 272 seconds) |
2024-09-30 18:13:26 +0200 | <Inst> | tomsmeding: something like just parensing a partially applied data constructor, but either case, Left / Right is like a special case, otherwise it's usually just begging for inconsistent types |
2024-09-30 18:13:01 +0200 | <lambdabot> | 1 |
2024-09-30 18:13:00 +0200 | <c_wraith> | > case Left "hello" of Left{} -> 1 ; Right{} -> 2 -- Inst |
2024-09-30 18:11:52 +0200 | <ski> | __monty__ : sometimes `join' is easier or clearer to write directly, rather than `(>>=)'. i was wondering what you similarly thought about `liftA2' vs. `(<*>)' |
2024-09-30 18:10:08 +0200 | <tomsmeding> | and without <*>? :p |
2024-09-30 18:09:33 +0200 | <__monty__> | ski: Presuming <*>, yes. |