我已经学习了 Haskell 大约一年,并提出了一个问题,有才华的编译器作者是否可以添加一个名为“子集”的新功能,以增强 Haskell 的类型系统以捕获许多错误,包括编译阶段的 IOExceptions。我是类型理论的新手,请原谅我的一厢情愿。
我最初的目的不是如何解决问题,而是要知道是否存在相关的解决方案,但由于某些原因,没有将解决方案引入 Haskell。
Haskell 在我心目中几乎是完美的,除了一些小事,我将在以下几行中表达我对 Haskell 未来的愿望。
以下是主要的:
如果我们可以定义一个类型,它只是Int
假设 Haskell 允许我们这样做的“子集”,如下所示:
data IntNotZero = Int {except `0`} -- certainly it is not legal in Haskell, but I just assume that Haskell allows us to define a type as a "subset" of an already existing type. I'm novice of Theory of types, and forgive me.
如果函数需要 的参数Int
,则 的变量IntNotZero
,它只是 的“子集” Int
,也可以是函数的参数。但是,如果一个函数需要 a IntNotZero
,那么 aInt
是非法的。
例如:
div' :: Int -> IntNotZero -> Int
div' = div
aFunction :: Int -> Int -> Int --If we casually write it, then the compiler will complain for type conflict.
aFunction = div'
aFunction2 :: Int -> Int -> Int --we have to distinguish between `Int` and `IntNotZero`.
aFunction2 m n = type n of --An assumed grammar like `case ... of` to separate "subset" from its complement. `case ...of` only works on different patterns.
IntNotZero -> m `div` n
otherwise -> m + n
举一个更有用的例子:
data HandleNotClosed = Handle {not closed} --this type infers a Handle not closed
hGetContents' :: HandleNotClosed -> IO String --this function needs a HandleNotClosed and a Handle will make a type conflict.
hGetContents' = hGetContents
wrongMain = do
...
h <- openFile "~/xxx/aa" ReadMode
... -- we do many tasks with h and we may casually closed h
contents <- hGetContents' h --this will raise a type conflict, because h has type of Handle not HandleNotClosed.
...
rightMain = do
...
h <- openFile "~/xxx/aa" ReadMode
... -- we do many tasks with h and we may casually closed h
type h of -- the new grammar.
HandleNotClosed -> do
contents <- hGetContents' h
...
otherwise -> ...
如果我们将普通 IO 与 Exception 组合成一个新的“supset”,那么我们可能会摆脱 IOErrors。