我有一个功能
sasiad (x,y) = [ (x+dx,y+dy) | dy <- [-1..1], dx <- [-1..1], x+dx >= 0, y+dy >= 0]
我不喜欢那个函数的类型。我希望它返回[(Int,Int)]
而不是[(t,t1)]
是否可以强制 ghci 做到这一点?
我有一个功能
sasiad (x,y) = [ (x+dx,y+dy) | dy <- [-1..1], dx <- [-1..1], x+dx >= 0, y+dy >= 0]
我不喜欢那个函数的类型。我希望它返回[(Int,Int)]
而不是[(t,t1)]
是否可以强制 ghci 做到这一点?
您可以添加类型注释作为 dave4420 提及,但这样做的正常方式是这样的:
sasiad :: (Int, Int) -> [(Int, Int)]
sasiad (x,y) = [ (x+dx,y+dy) | dy <- [-1..1], dx <- [-1..1], x+dx >= 0, y+dy >= 0]
但是,对于使用编译器推断的类型,需要提出一个论点:
sasiad :: (Ord t1, Ord t, Num t1, Num t, Enum t, Enum t1) => (t, t1) -> [(t, t1)]
正如这篇博文所述,更复杂的类型具有优势。例如,你的函数的推断类型区分t
和t1
意味着如果你声明这个类型,编译器不会让你混淆参数。基本上,这种类型保证结果列表中对的第一个元素x
仅使用计算,第二个元素仅使用计算y
。这是否是有用的不变量取决于您的程序。
另外,我不禁要重构您的功能:
sasiad :: (Ord t1, Ord t, Num t1, Num t, Enum t, Enum t1) => (t, t1) -> [(t, t1)]
sasiad (x,y) = cross (generate x) (generate y)
where generate x = filter (>=0) . map (\dx -> x+dx) $ [-1..1]
cross xs ys = [ (x,y) | x <- xs, y <- ys ]
是的,添加一个类型注释:
sasiad (x,y) = [ (x+dx,y+dy) | dy <- [-1..1], dx <- [-1..1], x+dx >= 0, y+dy >= 0] :: [(Int, Int)]