我正在传递部分应用的功能。完整的签名是:
import Data.Map as Map
-- Update the correct bin of the histogram based on the min value, bin width,
-- the histogram stored as a map, and the actual value we are interested in.
updateHist :: Double -> Double -> Map.Map Bin Double -> Double ->
Map.Map Bin Double
该函数更新存储直方图数据的Map。前两个参数给出了我们感兴趣的数据的下限,下一个是直方图的bin宽度。我在程序启动时填写这些值,并在整个模块中传递部分应用的函数。这意味着我有很多功能,签名如下:
-- Extra the data out of the string and update the histogram (in the Map) with it.
doSomething :: String -> (Map.Map Bin Double -> Double -> Map.Map Bin Double) ->
Map.Map Bin Double
这一切都很精致,但写作“(Map.Map Bin Double - > Double - > Map.Map Bin Double)”相当冗长。我想用“UpdateHistFunc”替换它们作为一种类型但由于某种原因我一直都失败了。
我试过了:
newtype UpdateHistFunc = Map.Map Bin Double -> Double -> Map.Map Bin Double
此操作因错误而失败:
HistogramForColumn.hs:84:44:输入` - >'解析错误
我做错了什么?
答案 0 :(得分:17)
您是否在这里混淆type
和newtype
?
使用type
定义类型同义词,这是您似乎要尝试做的事情,而newtype
创建一个需要构造函数名称的新类型,例如data
。< / p>
换句话说,你可能想要这个:
type UpdateHistFunc = Map.Map Bin Double -> Double -> Map.Map Bin Double
......或者可能是这样:
newtype UpdateHistFunc = UpdateHistFunc (Map.Map Bin Double -> Double -> Map.Map Bin Double)
后者显然需要“解开”才能应用该功能。
供参考:
data
定义了一种新的代数数据类型,它可以是递归的,具有不同类型类的实例,引入了一层可能的懒惰,所有这些。newtype
定义一个数据类型,其中一个构造函数采用单个参数,该参数可以是递归的并且具有不同的实例,但仅用于类型检查;在编译之后,它等同于它包含的类型。type
定义了一个类型同义词,它不能递归或具有不同的实例,在类型检查时完全展开,并且只比宏更多。如果您想知道data
和newtype
之间在“额外懒惰”方面的语义差异,请比较这两种类型以及它们可能具有的值:
data DType = DCon DType
newtype NType = NCon NType
例如,如果分别应用于undefined
与DCon undefined
和NCon undefined
,您认为这些功能会怎样?
fd (DCon x) = x
fn (NCon x) = x