Logs: liberachat/#haskell
| 2026-02-25 17:53:00 | <ski> | well .. this is module system dot, not quite the same thing ? |
| 2026-02-25 17:54:17 | <ski> | (typically module system have static, compile-time, resolvers. sometimes you can pass around modules at run-time, though, blurring the line a bit) |
| 2026-02-25 17:54:59 | <ski> | (e.g. in OCaml, and Alice ML) |
| 2026-02-25 17:56:15 | <EvanR> | it fills the same blank... single term dot stuff, which people like to latch their IDE features onto |
| 2026-02-25 17:57:11 | <ski> | (.. i'm not too sure how common it is to be able to define (e.g. abstract) data types inside an object, with OOP, though .. which routinely happens, with modules) |
| 2026-02-25 17:57:27 | <EvanR> | you mean inner class? |
| 2026-02-25 17:57:42 | <EvanR> | I know you don't mean that, but that's pretty common |
| 2026-02-25 17:59:14 | <ski> | i mean so that you can specify a functor (module function), that takes a module (with a type inside), and returns another module, with a `sharing' constraint saying that the type exported by the resulting module is the same as the type in the parameter module, so that other code can use values of one type where values of the other are expected |
| 2026-02-25 17:59:38 | <ski> | standard module system stuff you do in the ML module system |
| 2026-02-25 18:01:23 | <ski> | .. i'm not sure how easy it would be do express something like that, with the "module with abstract data type(s), as existentially quantified record" idiom for simulating modules, in e.g. Haskell |
| 2026-02-25 18:02:20 | <EvanR> | unfortunate past tense did backpack have this "functor" feature? |
| 2026-02-25 18:02:35 | <ski> | with `myFunctor :: (exists t. ..t..) -> (exists t. ..t..)', how would you ensure the two `t's are the same, *apart* from rewriting to `myFunctor :: forall t. (..t.. -> ..t..)' ? |
| 2026-02-25 18:03:16 | <EvanR> | myFunctor :: exists t . Sig1 t -> Sig2 t |
| 2026-02-25 18:03:17 | <EvanR> | xD |
| 2026-02-25 18:03:24 | <EvanR> | make that forall |
| 2026-02-25 18:03:36 | <ski> | (imagine there's a whole bunch of different abstract types, and one `t' is in a nested submodule, and perhaps the other one as well, and you'd like to not disturb all this structure, while still ensuring the two `t's are known to be equal) |
| 2026-02-25 18:03:55 | <EvanR> | ah you called it |
| 2026-02-25 18:04:07 | <ski> | yes |
| 2026-02-25 18:04:59 | <ski> | (iirc, you can also add sharing constraints for whole submodules) |
| 2026-02-25 18:05:20 | <EvanR> | so much stuff boils down to the management of scopes |
| 2026-02-25 18:07:15 | <ski> | yea |
| 2026-02-25 18:07:18 | <EvanR> | what's an example of a sharing constraint |
| 2026-02-25 18:07:44 | → | wickedjargon joins (~user@208.98.208.115) |
| 2026-02-25 18:09:08 | → | ljdarj joins (~Thunderbi@user/ljdarj) |
| 2026-02-25 18:09:22 | <__monty__> | Backpack was sold to me as bringing ML's functors to Haskell. |
| 2026-02-25 18:11:39 | × | yahb2 quits (~yahb2@user/tomsmeding/bot/yahb2) (Server closed connection) |
| 2026-02-25 18:12:02 | → | yahb2 joins (~yahb2@user/tomsmeding/bot/yahb2) |
| 2026-02-25 18:12:02 | ChanServ | sets mode +v yahb2 |
| 2026-02-25 18:12:58 | → | merijn joins (~merijn@host-cl.cgnat-g.v4.dfn.nl) |
| 2026-02-25 18:13:25 | <ski> | module Set.Make : functor (Ord : OrderedType) -> S with type elt = Ord.t |
| 2026-02-25 18:13:39 | <ski> | is one example, from OCaml, <https://ocaml.org/manual/5.4/api/Set.S.html> |
| 2026-02-25 18:14:54 | <EvanR> | so elt is defined in ... |
| 2026-02-25 18:15:18 | <ski> | given a parameter module `Ord', of signature `OrderedType' (equal to `sig type t val compare : t -> t -> int'), it constructs a module of signature `S' (including a type `elt' of set elements, a type `t' of sets, and various operations on sets) |
| 2026-02-25 18:16:07 | <ski> | and the `with type elt = Ord.t' ensures that it is known to callers of `Make' that the type `elt' in the resulting module will be equal to the type `t' in the parameter module |
| 2026-02-25 18:17:00 | <ski> | (otherwise, you would know nothing about `elt', except, perhaps, that it has a `compare' function (or any function defined in terms of that), assuming the result module exports that operation) |
| 2026-02-25 18:17:10 | <EvanR> | ok elt is in the resulting module |
| 2026-02-25 18:17:14 | <ski> | yes |
| 2026-02-25 18:17:36 | × | merijn quits (~merijn@host-cl.cgnat-g.v4.dfn.nl) (Ping timeout: 246 seconds) |
| 2026-02-25 18:17:39 | <EvanR> | Set.S |
| 2026-02-25 18:17:53 | <EvanR> | er Set |
| 2026-02-25 18:19:55 | <ski> | here's one SML example (from lambdaProlog implementation Terzo) : |
| 2026-02-25 18:21:00 | <ski> | functor Program (structure Lg : LOGICALS structure Lam : LAM structure Error : ERROR structure Module : MODULE structure UU : UUTILS structure IU : IU sharing type Lam.lterm = Module.lterm = IU.lterm = UU.lterm sharing type Lg.const = Module.const = Lam.const sharing type IU.tp = Lg.tp = Lam.tp = Module.tp) : PROGRAM = struct ... end |
| 2026-02-25 18:21:29 | jmcantrell_ | is now known as jmcantrell |
| 2026-02-25 18:21:54 | <ski> | here, the `sharing type ... = ...' constraints ensure that all the different parameter agree about the relevant types that are supposed to be the same over their interfaces/signatures |
| 2026-02-25 18:23:30 | <ski> | EvanR : well, strictly speaking `Make(Ord)' (`Set' is a functor, a module function. `elt' is in the output/result module, constructed by this) (and the functor `Make' itself is a component of the module `Set', so `Set.Make(Ord)') .. where `Ord' is whatever parameter module you decide to use |
| 2026-02-25 18:24:55 | → | uli-fem joins (~uli-fem@118.210.1.123) |
| 2026-02-25 18:24:56 | → | Milan_Vanca joins (~milan@88.212.61.169) |
| 2026-02-25 18:25:55 | <Milan_Vanca> | Hello guyz, is "let something = case of" forbiden in "do notation"? |
| 2026-02-25 18:26:04 | <ski> | no |
| 2026-02-25 18:26:26 | <ski> | (well, you need an expression between the `case' and `of'. assuming you just omitted that) |
| 2026-02-25 18:26:37 | <ski> | you likely have indentation off |
| 2026-02-25 18:27:03 | <ski> | make sure the branches after the `of' are indented more than the start of `something' |
| 2026-02-25 18:28:01 | <Milan_Vanca> | ski: I don't know.. to me code looks good |
| 2026-02-25 18:28:03 | <Milan_Vanca> | https://paste.tomsmeding.com/tCHM4xIg |
| 2026-02-25 18:28:27 | <EvanR> | indent lines Left and Right more |
| 2026-02-25 18:28:37 | <ski> | `Left' and `Right' must be indented at least three spaces more |
| 2026-02-25 18:28:48 | → | merijn joins (~merijn@host-cl.cgnat-g.v4.dfn.nl) |
| 2026-02-25 18:28:54 | <ski> | (one more than the `r' in `result') |
| 2026-02-25 18:29:15 | × | uli-fem quits (~uli-fem@118.210.1.123) (Ping timeout: 255 seconds) |
| 2026-02-25 18:29:42 | <EvanR> | that is so much equality constraints now I'm imagining things to do with them |
| 2026-02-25 18:29:47 | <ski> | .. also, instead of `... -> (...)', you can simply write `... -> ...' (extra brackets redundant) |
| 2026-02-25 18:30:06 | <EvanR> | could you encode category theory |
| 2026-02-25 18:30:14 | <Milan_Vanca> | ski: I added bracket as I thought this is root of error.. |
| 2026-02-25 18:30:31 | <ski> | ah |
| 2026-02-25 18:30:42 | <Milan_Vanca> | I don't understand the problem with indentation. It has one more indentaion as "let" and that should be enough |
| 2026-02-25 18:30:48 | <ski> | no |
| 2026-02-25 18:30:52 | <ski> | consider |
| 2026-02-25 18:30:59 | <ski> | let result = case ... of |
| 2026-02-25 18:31:06 | <ski> | Foo -> ... |
| 2026-02-25 18:31:12 | <ski> | anotherResult = case ... of |
| 2026-02-25 18:31:15 | <ski> | Foo -> ... |
| 2026-02-25 18:31:50 | <EvanR> | Milan_Vanca, let lets you define multiple things |
| 2026-02-25 18:31:59 | <Milan_Vanca> | At once? |
| 2026-02-25 18:31:59 | <ski> | any line which is at the same level of indentation as `result' is assumed to start a new defining equation, inside the `let' |
| 2026-02-25 18:32:01 | <EvanR> | yes |
| 2026-02-25 18:32:09 | <EvanR> | let x = ... |
| 2026-02-25 18:32:12 | <EvanR> | y = ... |
| 2026-02-25 18:32:15 | <EvanR> | z = ... |
| 2026-02-25 18:32:15 | <ski> | any line which is at *less* indentation than `result' ends the `let' block |
| 2026-02-25 18:32:24 | × | PaulMartensen quits (15a119e437@2001:bc8:1210:2cd8::3bc) (Ping timeout: 245 seconds) |
| 2026-02-25 18:32:24 | <ski> | yes |
| 2026-02-25 18:32:46 | → | PaulMartensen joins (15a119e437@2001:bc8:1210:2cd8::3bc) |
| 2026-02-25 18:32:59 | <ski> | for my example, you need to type |
| 2026-02-25 18:33:05 | <ski> | let result = case ... of |
| 2026-02-25 18:33:11 | <ski> | Foo -> ... |
| 2026-02-25 18:33:13 | <ski> | anotherResult = case ... of |
| 2026-02-25 18:33:15 | <ski> | Foo -> ... |
| 2026-02-25 18:33:38 | <Milan_Vanca> | ski: :D This is ugly |
| 2026-02-25 18:33:42 | <ski> | to make it clear when the next defining equation inside `let' starts, and then (after this), when the whole `let' block ends |
| 2026-02-25 18:33:45 | × | merijn quits (~merijn@host-cl.cgnat-g.v4.dfn.nl) (Ping timeout: 255 seconds) |
| 2026-02-25 18:33:49 | <Milan_Vanca> | This let can define multiple things is ugly :D |
| 2026-02-25 18:34:08 | <EvanR> | either don't try to do this case inside a let, or put the case on one line |
| 2026-02-25 18:34:22 | <EvanR> | if you don't want to just indent more |
| 2026-02-25 18:34:31 | × | bggd_ quits (~bgg@2a01:e0a:fd5:f510:37b0:d42d:8afb:890) (Remote host closed the connection) |
| 2026-02-25 18:34:45 | <ski> | you *could* do |
| 2026-02-25 18:34:48 | <ski> | let |
| 2026-02-25 18:34:49 | <EvanR> | if you want to emphasize the case, indent all the way past the case |
| 2026-02-25 18:34:53 | <ski> | result = case ... of |
| 2026-02-25 18:35:00 | <ski> | Left ... -> ... |
| 2026-02-25 18:35:04 | <ski> | Right ... -> ... |
All times are in UTC.