首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在haskell中的天际线,可能是因为“函数”被应用于太少的参数

在haskell中的天际线,可能是因为“函数”被应用于太少的参数
EN

Stack Overflow用户
提问于 2016-03-25 09:12:04
回答 1查看 1.1K关注 0票数 0

我正在为大学学习哈斯克尔,我正在尝试做一个天际线问题-> https://briangordon.github.io/2014/08/the-skyline-problem.html

我对haskell语法有严重的问题,因为我来自OO语言,FP对我来说很奇怪,所以,这是我当前的代码:

代码语言:javascript
复制
    type Edificio = (Int,Int,Int)
type Coordenada = (Int,Int)
type Skyline = [Coordenada]

resuelveSkyline :: [Edificio] -> Skyline
resuelveSkyline [] = []
resuelveSkyline [x] = edificioAskyline(x)
resuelveSkyline xs = combina (resuelveSkyline(fst(divide(xs))),resuelveSkyline(snd(divide(xs))))

edificioAskyline :: Edificio -> Skyline
edificioAskyline (x1,x2,h) = [(x1,h),(x2,0)]

divide :: [Edificio] -> ([Edificio], [Edificio])
divide edificios = splitAt (((length edificios) + 1) `div` 2) edificios

combina :: Skyline -> Skyline -> Skyline
combina (_,_) = []

我有两个问题,第一个是:

例如,我有一个类型Coordenada,如果我想传递一个Coordenada作为其他函数的参数,并且在它里面得到他的第一个元组值,我应该做什么?

第二个问题是,我在编译时出现了这个错误:

代码语言:javascript
复制
 Main.hs:8:22:
    Couldn't match type ‘Skyline -> Skyline’ with ‘[Coordenada]’
    Expected type: Skyline
      Actual type: Skyline -> Skyline
    Probable cause: ‘combina’ is applied to too few arguments
    In the expression:
      combina
        (resuelveSkyline (fst (divide (xs))), 
         resuelveSkyline (snd (divide (xs))))
    In an equation for ‘resuelveSkyline’:
        resuelveSkyline xs
          = combina
              (resuelveSkyline (fst (divide (xs))), 
               resuelveSkyline (snd (divide (xs))))

我知道合并还没有完成,但我想一点一点地尝试。

我有西班牙语,因为我必须使用这些函数名强制性(教授义务我们)。我会解释每一种方法。

resuelveSkyline有一个Edificio列表作为输入,并返回一个Skyline,它是主要功能。edificioASkyline有一个建筑物作为输入,并将其转换为天际线分隔,取一个列表并返回两个大小相同的列表。combina采取2天际线,并返回一个新的合并与两者。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-03-25 09:49:17

假设您想要定义func :: A -> B -> C。要定义func的语法是:

代码语言:javascript
复制
func :: A -> B -> C
func a b = ...
  -- ^^^

但是,如果使用(a,b),则不是使用两个单独的参数,而是使用单个参数:

代码语言:javascript
复制
--      vvvvv
func :: (A,B) -> C
func (a,b) = ...
--   ^^^^^

但是,GHC只在这一行中查看combina的类型签名:

代码语言:javascript
复制
resuelveSkyline xs = combina (resuelveSkyline(fst(divide(xs))),resuelveSkyline(snd(divide(xs))))

因此,尽管您已经将combina定义为处理元组,但它不键入check。请注意,combina's定义也不会与其指定的类型统一。

话虽如此,如果您更改了combina的类型并引入了一个助手,您可以使您的代码变得更容易:

代码语言:javascript
复制
combina :: (Skyline, Skyline) -> Skyline
combina  (a,b) = ...

both :: (a -> b) -> (a,a) -> (b,b)
both f (x,y) = (f x, f y)

resuelveSkyline xs = combina (both resuelveSkyline (divide xs))

练习

  1. 您可以将任何函数从(a, b) -> c更改为a -> b -> c。编写一个函数,该函数正是这样做的: fromPairFunc:(a,b) -> c) -> (a -> b -> c) fromPairFunc f=.
  2. 你也可以做相反的事情。编写相应的函数: toPairFunc:(a -> b -> c) -> (a,b) -> c) toPairFunc f=.
  3. 在您的原始代码中,不要更改combina的类型,而是更正它的定义,并在正确的位置使用toPairFunc
  4. 在原始代码中,更改combina的类型,但不要更改定义。而不是(resuelveSkyline(fst(divide(xs))),resuelveSkyline(snd(divide(xs)))),使用两个参数(resuelveSkyline(fst(divide(xs))))(resuelveSkyline(snd(divide(xs))))调用它。您必须在正确的位置使用toPairFunc
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36217095

复制
相关文章

相似问题

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