jtdaugherty / vty

A high-level ncurses alternative written in Haskell
BSD 3-Clause "New" or "Revised" License
319 stars 57 forks source link

Could `Event` use `Set Modifier` instead of `[Modifier]`? #246

Closed evanrelf closed 2 years ago

evanrelf commented 2 years ago

I was wondering if the Event type could use Set Modifier instead of [Modifier]?

I don't think the modifiers have an ordering, and pattern matching on a specific ordering of modifiers is error-prone.

jtdaugherty commented 2 years ago

Thanks for opening this. You're right that modifiers don't have an ordering. In my view, [Modifier] is not the right abstraction for what is going on anyway, and Set would be more appropriate. But I think the raw pragmatism of [Modifier] wins over Set just for pattern-matching the two simplest and most common cases: zero and one modifiers. If you need to go beyond that to check for multiple modifiers, guards can be used instead. (I don't know of any language extensions that add support for pattern-matching sets, although if one existed then that could be nice!)

evanrelf commented 2 years ago

In my view, [Modifier] is not the right abstraction for what is going on anyway, and Set would be more appropriate. But I think the raw pragmatism of [Modifier] wins over Set just for pattern-matching

That's a good point, and I agree 100% 👍

I don't know of any language extensions that add support for pattern-matching sets

Technically Set is an instance of the IsList type class, which powers the OverloadedLists language extension. That allows pattern matching on sets using list syntax. Unfortunately, it's implemented in terms of converting to and from a linked list, so you still have the problem of ordering when dealing with 2+ modifiers:

GHCi, version 9.0.2: https://www.haskell.org/ghc/  :? for help
ghci> :set -XOverloadedLists
ghci> import qualified Data.Set as Set
ghci> let mySet = Set.fromList [1, 2, 3]
ghci> case mySet of [3, 2, 1] -> "It works"; _ -> "It doesn't work"
"It doesn't work"
jtdaugherty commented 2 years ago

Yeah, pattern-matching on sets really would have to be aware of them as sets, not "list-like" things, in order to disregard ordering for comparisons.

A silver lining here might be that modifier support in terminals is generally abysmal and we are often lucky to get even one modifier to work correctly, let alone two, which perhaps makes lack of easy pattern-matching slightly less problematic. 😊