【发布时间】:2013-09-01 15:39:56
【问题描述】:
很抱歉,如果这个问题似乎经过深思熟虑,但我想知道是否可以在 Haskell 中为以下内容定义一致的语义:
derive Num String from Int where
get = read
set = show
derive Ord Bool from Integer where
get = fromEnum
set = toEnum
derive (Monad, Functor) Maybe from [] where
get (Just x) = [x]
get Nothing = [ ]
set [x] = Just x
set [ ] = Nothing
我看不出为什么不这样做,而且在某些情况下它似乎会减少样板文件,但我不知道是否(如果是,那么容易)这是否可以实现。
编辑:
我的意图是例如第一个例子被替换成这样的:
instance Num String where
get = read :: String -> Int
set = show :: Int -> String
a + b = set $ get a + get b
a * b = set $ get a * get b
...
【问题讨论】:
-
get?set?我认为你在问一些与 Haskell 所谓的推导完全无关的东西。你的意思是自动类型转换,对吧?这不是一个好主意。它剥夺了您从双向类型推导的好处,总而言之,它避免了比一些显式转换函数可以合理引入的更多样板。 — 此外,这些是特别不好的例子,因为这些类型甚至不是近似同构的。对于get "bla" :: Int、set (-1) :: Bool或set [1,2,3] :: Maybe Int之类的问题,您将如何处理? -
我认为应该可以在编译时用简单的实例声明替换声明,因此类型系统应该保持不变,尽管我同意这个提议与 Haskell 的派生机制完全无关;也许改名是为了。
-
什么声明应该被什么替换?你能举例说明你想如何使用它吗?
-
第一个示例的 get 函数无疑是部分的,我的意图是抛出模式匹配失败,但 get 和 set 永远不会暴露给用户,因此您的其他两个示例无关紧要。
-
我还是不太明白你对这一切有什么需求。 — 您提议的
instance Num String很好地显示了另一个问题:如果这样的事情在用户看到的情况下发生,那么他们将无法控制中间类型。为什么会是Int?用户可能需要"3.14159" + "2.71828"。为什么会是Double?用户可能需要"10"^"800" - 1。为什么Integer,他们可能需要"4 :+ 1" / "15"。等等等等。
标签: haskell syntax types macros syntactic-sugar