【问题标题】:custom type define in haskell在haskell中定义自定义类型
【发布时间】:2018-08-19 03:15:12
【问题描述】:

我是 haskell 的新手,我定义了一个自定义列表类型。但是当我尝试定义这个函数 mymaximum 时。我注意到它只有在 a 是 Num 类型时才有效。如果我希望它适用于所有类型,例如 Char,我应该改变什么?

data List a = ListNode a (List a) | ListEnd

mymaximum::List a -> a
mymaximum ListEnd = 0
mymaximum (ListNode x xs) 
    |  x > maxxs = x
    | otherwise = maxxs
    where maxxs = mymaximum xs

【问题讨论】:

    标签: haskell types max typeclass


    【解决方案1】:

    首先,如果您尝试加载给定的定义,则会收到错误消息,

    ....
     No instance for (Num a) arising from the literal `0'
     Possible fix:
       add (Num a) to the context of
         the type signature for mymaximum :: List a -> a
    ....
    

    所以这表明您需要将类型签名更改为

    mymaximum :: (Num a) => List a -> a
    

    现在错误信息是

    ....
    Could not deduce (Ord a) arising from a use of `>'
    from the context (Num a)
      bound by the type signature for mymaximum :: Num a => List a -> a
      at <interactive>:59:14-35
    Possible fix:
      add (Ord a) to the context of
        the type signature for mymaximum :: Num a => List a -> a
    ....
    

    同样,我们将类型签名更改为

    mymaximum :: (Num a, Ord a) => List a -> a
    

    现在 GHCi 响应:

    mymaximum :: (Num a, Ord a) => List a -> a
    

    意思是,它接受了带有类型签名的定义。

    现在这个函数将适用于所有实现NumOrd 类型类的类型。

    Int 是一个,Float 是另一个。 Char 不是。但是如果你import Data.Char,你可以使用函数

    chr :: Int -> Char
    
    ord :: Char -> Int
    

    要解决这个问题,通过将ord 映射到您的List Char 值(您还必须为此定义自己的map 函数......也许),找到您的最大值,然后使用@ 向后工作987654336@恢复字符。

    更新: 正如您所注意到的,将特殊大小写 0 作为空列表的最大值不是正确的做法。将一个元素列表作为您的基本案例是一个很好的解决方案。现在可以删除Num a 约束,并且该函数也可以用于List Char 参数或任何Ord a =&gt; List a 类型的值,从而产生Ord a =&gt; a 类型的值。

    但有一点需要注意:您仍然需要处理空列表的情况,可能通过调用 error 并带有特定的错误消息,例如

    mymaximum ListEnd = error " mymaximum: empty list is not allowed! "
    

    【讨论】:

    • 非常感谢!我会尝试你的解决方案。我只是想出了另一种方法来做到这一点。通过将我的基本情况更改为 mymaximum (ListNode x ListEnd) = x 并添加 Ord a 以键入签名工作。
    • 太棒了!事实上,使用0 是不正确的。另一方面,这意味着您的函数需要单独指定当它接收到ListEnd(即一个空列表)作为参数时要做什么。出现特定错误消息是一种可能性。另一个是将输出类型更改为Maybe a 并在空列表情况下返回Nothing
    猜你喜欢
    • 2011-12-20
    • 2012-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-19
    相关资源
    最近更新 更多