【发布时间】:2013-08-07 14:31:25
【问题描述】:
我的意图很简单。我想将a -> b 类型的函数包装到String -> String 中(以便可以将一堆异构函数放入列表中)。所以我写:
wrap :: (Read a, Show b) => (a -> b) -> (String -> String)
wrap f = \s -> show $ f (read s :: a)
但是,ghc 投诉:
Could not deduce (Read a1) arising from a use of `read'
from the context (Read a, Show b)
bound by the type signature for
wrap :: (Read a, Show b) => (a -> b) -> String -> String
我想知道为什么我的一段代码不能工作,以及需要什么样的 hack 来实现我的目标?
谢谢。
【问题讨论】:
-
将一堆异构函数放在一个列表中不是好的haskell,并且将它们全部包装在字符串转换中绝对是不好的haskell。从更大的意义上说,你想做什么?
-
这是一个错误。不要这样做。您正在抛弃 Haskell 强大的类型系统,以及与之相伴的所有出色的编译时检查。一个机械师告诉你你的车很好,然后它在高速公路上抛锚了,不像一个机械师告诉你花 50 美元修理一些会导致你坏掉的东西(现在,当它在车库里时)下来(后来,在造成更多损坏后,需要支付维修费,而修理它的人没有他需要的零件)。静态类型是一种很好的机制,动态类型是一种很好的机制。
-
@NovaDenizen 我绝对喜欢静态类型。最近我一直在写一个简单的服务器。
a -> IO b代表已实现的服务。一个组件是将[(String, a -> IO b)]转换为Map String (a -> IO b)。但是类型系统不允许这样做。我确实有更复杂的类型设计来强制类型安全(因此客户端必须将a类型的输入提供给a -> IO b类型的服务,否则整个程序将不会进行类型检查)。但问题是服务器可能根本没有为用 Haskell 编写的客户端提供服务。所以我的机制在这种情况下不起作用。 -
@AndrewC 另外我很好奇是否有一种方法可以在 Haskell 和其他静态类型的 FP 语言(比如 OCaml)之间强制执行类型安全?
标签: haskell functional-programming