首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >编译器无法确定“接受”函数的返回值的类型

编译器无法确定“接受”函数的返回值的类型
EN

Stack Overflow用户
提问于 2018-03-10 12:20:10
回答 2查看 84关注 0票数 1

我正在试图解决Haskell的99个问题,对于第四个问题,我首先尝试了这样一个解决方案

代码语言:javascript
运行
复制
myLength :: [a] -> Int
myLength [] = 0
myLength ys = go 1 ys
 where
  go :: Int -> [a] -> Int
  go n xs
   | ( (take n xs) == (take (n+1) xs) ) = n
   | otherwise = go (n+1) xs

但是,编译器给出了错误:

代码语言:javascript
运行
复制
Problem4.hs:10:8: error:
    • No instance for (Eq a1) arising from a use of ‘==’
      Possible fix:
        add (Eq a1) to the context of
          the type signature for:
            go :: forall a1. Int -> [a1] -> Int
    • In the expression: ((take n xs) == (take (n + 1) xs))
      In a stmt of a pattern guard for
                     an equation for ‘go’:
        ((take n xs) == (take (n + 1) xs))
      In an equation for ‘go’:
          go n xs
            | ((take n xs) == (take (n + 1) xs)) = n
            | otherwise = go (n + 1) xs
   |
10 |    | ( (take n xs) == (take (n+1) xs) ) = n
   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

据我所知,错误的原因是,当我们试图比较从(take n xs)(take (n+1) xs)返回的列表时,编译器事先不知道列表的类型,所以不能对它们进行比较,这就是为什么它会抱怨,所以在这行之前,我需要告诉编译器,这两个返回值都是相同的类型,类型是[a],但是我们如何做到这一点呢?

A混淆:当我们指定go的类型签名时,我们显式地修正了xs的类型,也就是说,函数take返回的列表不应该具有相同的类型,即[a],因此编译器难道不能比较它们吗?

编辑:

请注意,我在函数的定义中有另一个函数,并且有许多与标记为重复的问题不同的地方,正如您所观察到的,给出的问题的答案并不能完全解决这个问题。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-03-10 12:30:55

您需要的是实例上下文(此处为Eq a),它由=>指示

代码语言:javascript
运行
复制
myLength :: Eq a => [a] -> Int
myLength [] = 0
myLength ys = go 1 ys
 where
  go :: Eq a => Int -> [a] -> Int
  go n xs
   | ( (take n xs) == (take (n+1) xs) ) = n
   | otherwise = go (n+1) xs

但这并不是问题4的正确答案,因为它为函数添加了额外的约束。

编辑:对于这个问题,“难道不是每个列表都是相等的吗?”

列表是可比较的当且仅当它们的元素是可比的。例如,函数、Kleisli箭头、WrappedArrow不相等,它们的列表也是不可比拟的。

票数 2
EN

Stack Overflow用户

发布于 2018-03-10 12:47:11

代码语言:javascript
运行
复制
{-# Language ScopedTypeVariables #-}

myLength :: forall a. Eq a => [a] -> Int
myLength [] = 0
myLength ys = go 1 ys
 where

  go :: Int -> [a] -> Int
  go n xs
   | take n xs == take (n+1) xs = n
   | otherwise = go (n+1) xs
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49209012

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档