Tôi mới tham gia FP và Scala và đang đọc cuốn sách Lập trình chức năng trong Scala. Một trong các bài tập trong Chương 4 yêu cầu chúng tôi viết một hàm có tên là sequence
sẽ chuyển đổi một số List[Option[A]]
thành một số Option[List[A]]
. Ở đây Option
là một reimplementation của Option
được cung cấp bởi thư viện Scala. Đây là mã được yêu cầu.Danh sách chuyển đổi [Tùy chọn [A]] thành Tùy chọn [Liệt kê [A]] trong Scala
trait Option[+A] {
/* Function to convert Option[A] to Option[B] using the function passed as an argument */
def map[B](f: A => B): Option[B] = this match {
case None => None
case Some(v) => Some(f(v))
}
/* Function to get the value in `this` option object or return the default value provided. Here,
* `B >: A` denotes that the data type `B` is either a super-type of `A` or is `A`
*/
def getOrElse[B >: A](default: => B): B = this match {
case None => default
case Some(v) => v
}
/* Used to perform (nested) operations on `this` and aborts as soon as the first failure is
* encountered by returning `None`
*/
def flatMap[B](f: A => Option[B]): Option[B] = {
map(f).getOrElse(None)
}
}
case class Some[+A](get: A) extends Option[A] // used when the return value is defined
case object None extends Option[Nothing] // used when the return value is undefined
Bây giờ tôi đã cố gắng rất nhiều, nhưng tôi đã phải tìm kiếm các giải pháp cho các văn bản sequence
, đó là,
def sequence[A](l: List[Option[A]]): Option[List[A]] = l match {
case Nil => Some(Nil) // Or `None`. A design decision in my opinion
case h :: t => h.flatMap(hh => sequence(t).map(hh :: _))
}
Tôi chỉ muốn chắc chắn rằng tôi hiểu các giải pháp một cách chính xác. Vì vậy, đây là những câu hỏi của tôi.
- Trực giác của tôi về giá trị trả lại cho
case Nil
có đúng không? Nó thực sự là một quyết định thiết kế hoặc là một cách tốt hơn so với khác? - Đối với
case h :: t
, đây là những gì tôi đã hiểu. Chúng tôi vượt qua giá trịh
trước hết đến chức năng ẩn danh trongflatMap
(dưới dạnghh
) gọi sốsequence
đệ quy. Cuộc gọi đệ quy này củasequence
trả về một sốOption
đóng góiOption
s trongt
. Chúng ta gọimap
trên giá trị trả về này và vượt quah
đến hàm ẩn danh (nhưhh
), sau đó tạo mộtList[A]
mới với danh sách được trả về bằng cách gọi đệ quy làm đuôi vàh
làm đầu. Giá trị này sau đó được đóng gói trongOption
bằng cách gọiSome
và trả lại.
Sự hiểu biết của tôi về phần thứ hai có đúng không? Nếu có, có cách nào tốt hơn để giải thích nó không?
Vấn đề với phiên bản 'fold' là Danh sách kết quả không duy trì trật tự; nó trở nên đảo ngược. – borice
Bạn muốn sử dụng 'sofar: + value' thay cho' value :: sofar' trong câu lệnh case để nối vào cuối danh sách cho đến nay. – borice