2

我认为 Haskell 中的元组就像

  tuple :: (a,b)

这意味着 a 和 b 可以是相同的类型,也可以是不同的类型

因此,如果我定义一个函数而不给出它的类型,那么当我在 ghci 中编写 :t 函数时,我可能会得到 (t,t1) 或一些不同的类型。那么是否有可能只获得相同的类型而不在函数中定义它。我听说它在 haskell 中是不允许的

所以我不能写一些像

  function [(x,x)]=[(x,x,x)]

得到

  :t function
     function :: [(a,a)]->[(a,a,a)]

这是我正在尝试做的一个练习,这个练习希望我在不定义类型的情况下编写一个函数。例如获取

  Bool->(Char,Bool) 

当我给

  :t function

在 ghci 中。我应该写——

  function True=('A',True)

我不允许定义函数的类型部分所以我不能写

  function::(Eq a)=>[(a,a)]->[(a,a,a)]

或类似的东西

4

6 回答 6

6

您可以使用asTypeOfPrelude 中的函数将元组的第二个组件的类型限制为与第一个组件的类型相同。例如,在 GHCi 中:

> let f (x, y) = (x, y `asTypeOf` x, x)

> :t f
f :: (t, t) -> (t, t, t)
于 2013-05-16T11:37:56.137 回答
4

您可以愉快地将类型限制为等价.. 通过写出所需的类型。

type Pair a = (a,a)
type Triple a = (a,a,a)

接着:

fn :: [Pair a] -> [Triple a]

将强制执行您想要的约束。

于 2013-05-16T10:56:43.277 回答
2

以下应该在没有 的情况下工作asTypeOf

trans (a,b) = case [a,b] of _ -> (a,b,a)
function xs = map trans xs
于 2013-05-16T12:49:15.980 回答
2

type正如唐所说,您可以使用。或者,如果您不想为此烦恼(也许您只需要一个函数),您可以像这样指定函数的类型签名:

function :: [(a,a)] -> [(a,a,a)]
function xs = map (\(a, b) -> (a, b, a)) xs -- just an example
于 2013-05-16T11:26:08.057 回答
2

我猜你正在寻找的是asTypeOf功能。使用它,您可以将某个值的类型限制为与函数定义中的另一个值的类型相同。例如:

Prelude> :t \(a, b) -> (a, b `asTypeOf` a)
\(a, b) -> (a, b `asTypeOf` a) :: (t, t) -> (t, t)
于 2013-05-16T11:37:21.340 回答
1

好的,如果我正确理解了这一点,那么您遇到的问题实际上与类型无关。你的定义,

function [(x,x)]=[(x,x,x)]

将不起作用,因为您实际上是在说“如果 to 的参数 function是一个包含一个元素的列表,并且该元素是一个元组,那么调用然后绑定x到元组的第一部分绑定 x到第二部分元组”。您不能一次将符号绑定到两个表达式。

如果您真正想要的是确保元组的两个部分相同,那么您可以执行以下操作:

function [(x,y)] = if x == y then [(x,x,x)] else error "mismatch"

或这个:

function2 [(x,y)] | x == y = [(x,x,x)]

...但是当元组的部分不匹配时,这将失败。

现在我怀疑您真正想要的是处理具有多个元素的列表。因此,您可能想要执行以下操作:

function3 xs = map f xs
  where f (x, y) = if x == y then [(x,x,x)] else error "mismatch"

这些函数中的任何一个都将具有您想要的类型,Eq t => [(t, t)] -> [(t, t, t)]而无需您指定它。

于 2013-05-16T11:41:34.650 回答