![](/img/trans.png)
[英]Can a function operating upon mutable data structure be referentially transparent?
[英]Designing referentially transparent function for reading from channel
我試圖堅持純FP風格,並希望設計一個參照透明功能。
我有一個java.nio.channels.SeekableByteChannel
,它是一個數據源。 打開文件並獲取SeekableFileChannel
實例后,我需要讀取文件的第一行,並使用這些行確定查找位置。
因此,我創建了以下函數:
object AdjustChannelAndGetStream {
def apply(ch: SeekableFileChannel)
(firstChunksToOffset: List[Array[Byte]] => Long): fs2.Stream[Id, Array[Byte]] {
val offset = //depending on the first bytes read from the file
//get the number of bytes read before
val newChannel = ch.position(offset)
//finally wrap newChannel into fs2.Stream
}
}
問題是,該函數看起來很丑。 它不會暫停副作用,這使其難以測試(模擬SeekableByteChannel
)。
我傾向於將SeekableByteChannel
包裝到IO[SeekableByteChannel]
(Scalaz / Cats無關緊要),但是我看不到它有什么幫助(我們需要相同的SeekableByteChannel
mock
,但現在包裝到IO
)。
您能否幫助我以純FP樣式設計此功能(或至少使其不那么難看)?
當您需要包裝不純凈的代碼時,大多數時候(根據我的經驗),它不會變得“漂亮”。 但是,我們得到的是,只有一個點可以處理“混亂的東西”,並且從那里可以得到很好的抽象。
我們想要的是創建一個受IO
效果約束的流。 實際上,我們位於Stream[IO, SeekableByteChannel]
Stream[Id, SeekableByteChannel]
而不是Stream[Id, SeekableByteChannel]
,因為我們處於IO
效果上下文中:
import java.nio.channels.SeekableByteChannel
import cats.effect.IO
object AdjustChannelAndGetStream {
def apply(ch: SeekableByteChannel)(
firstChunksToOffset: List[Array[Byte]] => Long)
: fs2.Stream[IO, SeekableByteChannel] = {
fs2.Stream.eval {
IO {
val offset: Int = ???
ch.position(offset)
}
}
}
}
這樣,我們暫停了副作用,這就是我們想要進行這些副作用計算RT的過程,並從此開始對流應用轉換。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.