bPspGiJT8Y
Joined 3 years ago
Joined 3 years ago
This is possible to achieve (or hack your way through, if you will) by parameterizing the type and using a nullary type (a type which is impossible to have) to exclude specific cases of a sum type. In Haskell this would look like this:
data Weather a b c = Sunny a | Rainy b | Snowy c
-- can't snow in the summer!
onlySummerWeather :: forall a b. Weather a b Void -> String
onlySummerWeather weather = case weather of
Sunny _ -> "Got sunny weather"
Rainy _ -> "Got rainy weather"
Snowy v -> absurd v
where `absurd :: forall a. Void -> a` "if you give me something you can't ever have, I will give you anything in return".That's an interesting idea. Do you have a link to show how you did this?
You're right, my memory has let me down.
> Do you have any pointers for the "load on tab" idea? I didn't turn up any good results in DDG and LLMs were just hallucinating.
The simplest implementation would be something like
bindkey ^I init_completions
init_completions () {
# ... init logic here ...
# rebind tab to complete
bindkey ^I complete-word
# actually do complete the initial request
zle complete-word
}
Edit: I see now you already figured it out, yeah that's exactly what I meantI'm curious where did you get that from.
Edit: I read the note in your dotfiles repo. Yes calling `compinit` on each shell invocation is going to be really slow. That's not how you're supposed to do it, you could at least add the `-C` flag to cache the completions. Ideally you'd also use `zcompile` to compile the cache to ZSH word code. This puts my completions initializing time at ~20ms on a lower/mid-end laptop. Additionally you can do the trick `fish` does and defer the initialization of completions until the first hit of Tab key, so the impact on shell startup time is exactly 0.
Programs can pollute it all they want, since I don't use it myself I also don't have to care about that.
splitString :: { pattern :: String, string :: String } -> Array String
splitString { pattern, string } = ...
This function would use positional arguments: splitString :: Pattern -> String -> Array String
splitString pattern string = ...Sorry, I must've been more explicit instead of implying certain usage patterns. What I meant here is that I have a hard time imagining this happening because I would start working on a function by writing its type signature. Unless my types check out, I won't be able to mark this function as "done" and jump to another part of code. So the situation "you return the partial assuming it's a number" simply can not happen, that's exactly what type checking is for. By the time I use it in another place, it has to already have been type checked.
So could you elaborate to me where the distinction lies here and why is there a need to "simulate" things?
I will get a type error and it will take me 2-3 seconds to figure out what it is about.
> Why on earth would you want to get a type error in a completely different part of the code because you got a function instead of an integer?
Why would it be in a completely different part of the code? At most it would be 2 lines away, but usually on the same line.
Maybe you could recall which learning materials you used?