2017-10-14 162 views
0

我无法获得此方法。一直都在犯错误。我在哪里犯错误?它应该接受字符串数组,取头,创建一个点。不过,我认为问题出在递归调用中。Haskell返回自定义数据类型

data Point = Point(Int, Int) -- y, x 
instance Show Point where 
    show (Point(y, x)) = "(" ++ show x ++ "," ++ show y ++ ")" 

gimmePoints :: String -> Point      
gimmePoints (x:xs) = do Point(1,2) 
         gimmePoints xs 
+0

你是什么意思的“字符串数组”,假设Point构造函数需要两个数字?他们是如何分开的? – Tobias

+0

'Point'没有'Monad'实例,所以不能使用'do'符号。另外,你的''Point'类型是双重包装坐标。没有必要将这两个点封装在一个元组中;它们可以简单地由'Point'构造函数本身包装:'data Point = Point Int Int'。 – chepner

+0

您是否正在学习基于教程的Haskell?因为'gimmePoints'功能很生硬,所以没有多大意义。目前还不清楚它应该做什么,更不用说它实际上做了什么。我建议放慢脚步,尝试一个更简单的任务,或许更符合初学者的Haskell指南,如[LYAH](http://learnyouahaskell.com/chapters)。 –

回答

3

如果你的函数有签名... -> Point,这意味着其结果应该是一个点。没有其他的。所以你当然可以写

gimmePoints :: String -> Point      
gimmePoints (x:xs) = Point(1,2) 

这意味着当然只有字符串中的第一个字符将被处理。事实上,因为你实际上并不使用该字符或任何以任何方式在字符串中一样,你还不如写为

gimmePoints _ = Point(1,2) 

我不认为这是你想要的。无论如何

do语法不作任何意义在这里,这是一元(“侧effectful”)行动。举例来说,如果你想为每个字符被打印到屏幕上的点,你可以做

gimmePoints' (_:xs) = do 
     print $ Point(1,2) 
     gimmePoints' xs 

在这种情况下,gimmePoints结果不会Point所有,而是没有一个IO动作结果(因为“结果”发送到不是屏幕)

gimmePoints' :: String -> IO() 

你实际上可以想一个更明智的,或者至少更多的功能编程十岁上下的版本是

gimmePoints'' :: String -> [Point] 
gimmePoints'' [] = [] 
gimmePoints'' (_:xs) = Point (1,2) : gimmePoints'' xs 

即对于字符串中的每个字符,您在结果中产生一个点。这实际上可以写得更好

gimmePoints'' = map (const $ Point (1,2)) 
+0

谢谢您的解释。工作。 –