首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >haskell函数声明

haskell函数声明
EN

Stack Overflow用户
提问于 2011-02-22 09:07:16
回答 3查看 941关注 0票数 6

我一直在尝试haskell,我发现如果我在代码文件中编写以下函数:

代码语言:javascript
复制
f :: Int -> [a] -> a
f idx str = last $ (take . succ) idx str

这样就可以很好地工作。当然,我认为没有参数的代码看起来会更好。

代码语言:javascript
复制
f :: Int -> [a] -> a
f = last $ (take . succ)

但是,当我试图将它加载到gchi中时,这会产生一个错误。

代码语言:javascript
复制
Couldn't match expected type `[a]'
       against inferred type `Int -> [a1] -> [a1]'
In the second argument of `($)', namely `(take . succ)'
In the expression: last $ (take . succ)
In the definition of `f': f = last $ (take . succ)

失败,模块已加载:无。

我有点困惑这是怎么发生的.

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-02-22 09:35:18

这就是尝试用(take . succ)合成last时会发生的情况

代码语言:javascript
复制
:t (.)
(.) :: (b -> c) -> (a -> b) -> a -> c

last :: [t] -> t  ~ (b -> c)  
-- so b ~ [t] and c ~ t   

(take . succ) :: Int -> [t] -> [t]  
-- so a ~ int and b ~ [t] -> [t]  

B的类型从last推断为[t],但它与(take . succ)中的b的类型[t] -> [t]不匹配

票数 6
EN

Stack Overflow用户

发布于 2011-02-22 09:13:54

你误解了优先顺序。这一点:

代码语言:javascript
复制
f idx str = last $ (take . succ) idx str

是这样解析的:

代码语言:javascript
复制
f idx str = last $ ( (take . succ) idx str )

不是(如你所想的)这样的:

代码语言:javascript
复制
f idx str = ( last $ (take . succ) ) idx str

在所有运算符中,$的优先级极低,而函数调用的优先级极高。.的值是第二高的,所以(take . succ)在绑定到last $之前先绑定到它的参数(idx str)。

此外,这个函数(在编译时)并不像您希望的那样工作。它递增idx,然后从字符串中获取该字符。如果这就是你想要的,为什么要在(+1)工作的时候使用succ呢?您已经将类型限制为整数。

正如所写的,您的函数与!!运算符相同-它只是一个数组索引函数。这是你想要的吗?或者您想在给定索引处对项目执行succ操作?您可以通过以下方式来完成此任务:

代码语言:javascript
复制
f :: Enum a => Int -> [a] -> a
f idx str = succ $ str !! idx
-- or
f idx str = succ $ (!!) str idx
-- or, only one argument
f idx = succ . (!! idx)

我仍在开发一个没有书面参数的版本。也许编写工作代码更重要?;)

票数 10
EN

Stack Overflow用户

发布于 2011-02-22 10:36:29

代码语言:javascript
复制
f idx str = last $ (take . succ) idx str
-- applying definition of ($)
f idx str = last ((take . succ) idx str)
-- adding parentheses for clarity
f idx str = last (((take . succ) idx) str)
-- using definition of (.)
f idx str = (last . (take . succ) idx) str
-- η-conversion
f idx = last . (take . succ) idx
-- infix to prefix notation
f idx = (.) last ((take . succ) idx)
-- ading parentheses for clarity
f idx = ((.) last) ((take . succ) idx)
-- using definition of (.)
f idx = ((.) last . (take . succ)) idx
-- η-conversion
f = (.) last . (take . succ)
-- remove parentheses: (.) is right-associative
f = (.) last . take . succ
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5073058

复制
相关文章

相似问题

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