简体   繁体   English

初学Haskell:使用反向功能进行最后一个功能

[英]Beginner Haskell: Making a last function with reverse

I'm attempting to make a function that generates the last item in a list. 我正在尝试制作一个生成列表中最后一项的函数。 I want to use reverse and !!. 我想使用反向和!!。 This is what I have so far: 这是我到目前为止的内容:

myLast :: [a] -> [a] -> Int -> a
myLast xs = (reverse xs) !! 1

I know the problem lies somewhere within the type, but I'm having trouble identifying how to fix it. 我知道问题出在类型中,但是我在确定如何修复它时遇到了麻烦。

A function's type signature has nothing to do with what you use in the function, it only describes how other people can use this function you're defining . 函数的类型签名与您函数中使用的内容无关,它仅描述其他人如何使用您正在定义的函数。 So by writing 所以写

myLast :: [a] -> [a] -> Int -> a

you're saying, users need to supply two lists and and integer. 您的意思是,用户需要提供两个列表和和整数。 Just to get the last element of one of the lists?? 只是为了获得列表之一的最后一个元素? That doesn't make sense. 那没有道理。

You surely mean 你一定是说

myLast :: [a] -> a

You should generally write that down before even thinking about how you're going to implement that function. 通常,您甚至应该在考虑如何实现该功能之前就写下来。

With that signature, you can write various implementations: 使用该签名,您可以编写各种实现:

myLast :: [a] -> a
myLast xs = head $ reverse xs

myLast' :: [a] -> a
myLast' [l] = l
myLast' (_:xs) = myLast' xs

myLast'' :: [a] -> a
myLast'' = fix $ \f (x:xs) -> maybe x id . teaspoon $ f xs

or whatever weird implementation you choose, it has nothing to do with the signature. 或您选择的任何奇怪的实现,都与签名无关。

On an unrelated note: though last is actually a standard function from the prelude, it's a kind of function avoided in modern Haskell: last [] gives an error, because the is no a value to be found in the empty list! 在一个不相关的注意事项:虽然last实际上是从前奏的标准功能,它是一种功能在现代哈斯克尔避免: last []给出了一个错误,因为没有 a在空列表中找到价值! Errors are bad. 错误很严重。 Hence the “ideal” way to write it is actually 因此,写它的“理想”方式实际上是

myLast :: [a] -> Maybe a
myLast [] = Nothing
myLast [x] = x
myLast (_:xs) = myLast xs

I would recommend not using !! 我建议不要使用!! at all, but to use head . 完全可以,但是要使用head

myLast xs = head (reverse xs)

Head returns the first element of the list it is given as argument. Head返回列表的第一个元素作为参数。
If you insist on using !! 如果您坚持使用!! , in Haskell arrays are indeed zero-based, which means that !! 0 ,在Haskell数组中的确是从零开始的,这意味着!! 0 !! 0 gets the first element, !! 1 !! 0是第一个元素!! 1 !! 1 the second, etc. !! 1秒,依此类推

As for the type: myLast takes an array of some type and returns one item of that same type. 至于类型: myLast采用某种类型的数组并返回相同类型的一项。 That is denoted as follows: 表示如下:

 
 
 
 
  
  
  myLast :: [a] -> a
 
 
  

@leftaroundabout covered this way better in his answer. @leftaroundabout在他的回答中更好地涵盖了这种方式。

Based on @leftaroundabout 's answer, here's an implementation that should do what you want: 基于@leftaroundabout的答案,这是一个应该执行您想要的操作的实现:

safeHead :: [a] -> Maybe a
safeHead [] = Nothing
safeHead (x:_) = Just x

myLast :: [a] -> Maybe a
myLast [] = Nothing
myLast xs = safeHead $ reverse xs

The Maybe type is constructed as follows (from Hackage ): Maybe类型的构造如下(来自Hackage ):

data  Maybe a  =  Nothing | Just a
  deriving (Eq, Ord)

myLast [1, 2, 3, 4] , for example, will return Just 4 . 例如, myLast [1, 2, 3, 4]将返回Just 4 If you want to use the value 4 you can use the function fromJust function from the Data.Maybe module ( fromJust (Just 4) returns 4 ). 如果要使用值4 ,则可以使用Data.Maybe模块中的 fromJust函数( fromJust (Just 4)返回4 )。 fromJust is defined like this: fromJust的定义如下:

-- | The 'fromJust' function extracts the element out of a 'Just' and
-- throws an error if its argument is 'Nothing'.
--
-- ==== __Examples__
--
-- Basic usage:
--
-- >>> fromJust (Just 1)
-- 1
--
-- >>> 2 * (fromJust (Just 10))
-- 20
--
-- >>> 2 * (fromJust Nothing)
-- *** Exception: Maybe.fromJust: Nothing
--
fromJust          :: Maybe a -> a
fromJust Nothing  = error "Maybe.fromJust: Nothing" -- yuck
fromJust (Just x) = x

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM