[英]How to use scalaz's `Tagged Type` to replace my type alias?
我想将对象定义为函数,并将其依赖于其他函数:
type FetchPage = String => String
type FindImages = String => List[String]
object WillFetchPage extends FetchPage {
def apply(url:String):String = /* get content of the url */
}
class WillFindImages(fetchPage: FetchPage) extends FindImages {
def apply(url:String):List[String] = {
val html = fetchPage(url)
// get image srcs from the <img> tags
}
}
然后我可以将WillFetchPage
注入WillFindImages
:
val findImages = new WillFindImages(WillFetchPage)
还可以通过注入一个模拟函数WillFindImages
轻松测试WillFindImages
:
val testFindImages = new WillFindImages(_ => "html-have-3-images")
val images = testFindImages("any-url")
// assertion
您可以看到类型别名FetchPage
只是类型别名,因此我可以错误地将其他String => String
函数传递给WillFindImages
,因此我正在寻找一种类型安全的解决方案。
然后我从scalaz听说了Tagged type
: http ://eed3si9n.com/learning-scalaz/Tagged+type.html
该示例令人兴奋:
sealed trait KiloGram
def KiloGram[A](a: A): A @@ KiloGram = Tag[A, KiloGram](a)
val mass = KiloGram(20.0)
2 * mass
您可以看到这里的mass
实际上是20.0
的两倍,但是它具有一些唯一的类型。
我想用它来改进我的代码,但可惜我找不到一种方法。 我试过了:
object FetchPage extends ((String => Try[String]) @@ FetchType)
但是它提供了一个编译错误:
Error:(18, 51) class type required but String => scala.util.Try[String] with
scalaz.Tagged[object_as_func.FetchType] found
object FetchPage extends ((String => Try[String]) @@ FetchType) {
^
如何解决?
您使用什么scalaz版本? 在7.0.6和7.1.0中有所不同。 这是7.1.0的示例
import scalaz.@@
object PageFetcher
type FetchPage = String => String
type FindImages = String => List[String]
val WillFetchPage: FetchPage @@ PageFetcher.type =
scalaz.Tag[FetchPage, PageFetcher.type](url => "Content")
class WillFindImages(fetchPage: FetchPage @@ PageFetcher.type) extends FindImages {
def apply(url: String): List[String] = scalaz.Tag.unwrap(fetchPage)(url).grouped(1).toList
}
val images = new WillFindImages(WillFetchPage)("url")
println(images)
val testFetcher: FetchPage @@ PageFetcher.type =
scalaz.Tag[FetchPage, PageFetcher.type](url => "TestContent")
val testImages = new WillFindImages(testFetcher)("url")
println(testImages)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.