Haskell新手麻烦,将列表分成两半 [英] Haskell Novice Trouble with Splitting a List in Half

查看:428
本文介绍了Haskell新手麻烦,将列表分成两半的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  halve :: [ a]  - > ([a],[a])
减半x
|甚至len =(取一半x,减半x)
|否则=错误Cannnot减少奇数长度的列表
其中
len =长度x
half = len / 2

我得到以下错误:

 没有实例for(Fractional Int )在表达式中:len / 2 
在'half'的等式中:half = len / 2
在'halve'的等式中:

我不明白错误,但我怀疑Haskell需要事先告知len是可以用2除的东西。那么,我该如何纠正这个例子呢?我的代码是否接近惯用的haskell?

>用于当你很高兴有一个非整数的答案。既然你已经检查过这个数字,你可以用 div 来简单地使用整数除法:

  halve :: [a]  - > ([a],[a])
减半x |甚至len =(取一半x,减半x)
|否则=错误Cannnot减少奇数长度的列表
其中len =长度x
half = len`div` 2

(我个人很乐意将一个奇数长度的列表精确地减半,并避免错误信息,但这取决于您。)

 (/):: Fractional a => a  - > a  - > a 
div :: Integral a => a - > a - > a

所以您只能在 / 时使用该类型支持非整数除法,并且当它是整数类型时,只能使用 div 。这样,当你真的在做另一种划分时,你不会认为你正在做一种划分。



顺便说一句,重新思考问题。



没有实例用于...



实际上,No instance对于......错误消息几乎总是因为某种错误类型。当我以错误的顺序输入参数时,我经常得到它。在这种情况下,当您输入 Int 时,您已经使用了其他类型的分配。



它表示没有实例,因为您尝试使用的函数适用于一类类型,但是您提供的数据类型不是在该类的一个实例中。编译器认为这是一个缺少的实例声明,多数情况下这只是一个错误,完全是错误的类型。我很少打算把某个事物做成一个班级的实例,然后忘记,而我更经常将参数放在错误的地方。


Here's my attempt to write a function that splits a list of even length into two equal halves.

halve :: [a] -> ([a], [a])
halve x 
   | even len = (take half x, drop half x)
   | otherwise = error "Cannnot halve a list of odd length"
   where
      len = length x
      half = len / 2

I am getting the following error:

 No instance for (Fractional Int) arising from a use of ‘/’
    In the expression: len / 2
    In an equation for ‘half’: half = len / 2
    In an equation for ‘halve’:

I don't understand the error but I have a suspicion that Haskell needs to be told in advance that len is something you can divide by 2. So, how do I rectify the example? Is my code anywhere near idiomatic haskell? I'd appreciate any other comments regarding my code.

解决方案

The / is used for when you're happy to have a non-integer answer. Since you've already checked the number's even, you can hapily use integer division with div:

halve :: [a] -> ([a], [a]) 
halve x | even len = (take half x, drop half x) 
        | otherwise = error "Cannnot halve a list of odd length" 
   where len = length x 
         half = len `div` 2

(Personally I'd be happy to halve an odd length list inexactly and avoid an error message, but that's up to you.)

This distinction is indicated by the types:

(/) :: Fractional a => a -> a -> a
div :: Integral a => a -> a -> a 

so you can only use / when the type supports non-integer division, and you can only use div when it's a whole-number type. That way you can't make a mistake thinking you're doing one sort of division when you're actually doing another.

Well done, by the way, you're thinking stuff through well.

"No instance for... "

Actually, the "No instance for ..." error message is almost always because something's the wrong type. I most frequently get it when I've put arguments in the wrong order. In this case you've had is for using the othetr sort of divition when yout type is Int.

It says "No instance" because the function you're trying to use works for a class of types, but the type of the data you're giving isn't in (an instance of) that class. The compiler sees this as a missing instance declaration, where more often than not it's just a mistake and it's the wrong type altogether. I very rarely intend to make something an instance of a class and then forget, whereas I more often put arguments in the wrong place.

这篇关于Haskell新手麻烦,将列表分成两半的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆