Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 9 additions & 6 deletions backend/junior-3/haskell.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
* [Introduction to Tagless Final](https://serokell.io/blog/2018/12/07/tagless-final)


## TypeOperators and type classes extensions:
## TypeOperators and type classes extensions

* `TypeOperators`
* `FlexibleContexts` & `FlexibleInstances`
Expand Down Expand Up @@ -127,7 +127,7 @@
* `ScopedTypeVariables`
* What is the main goal of this extension?
* Higher ranked types
* What is a "rank" of a function?
* What is a higher rank function?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Вопрос "как определяется ранг функции", на мой взгляд - вполне корректный и не нуждается в удалении. Можно пояснить, почему он заменяется на "что такое функция высшего ранга"? Это более слабый вопрос, поскольку в нём не уточняется, например, чем именно отличается функция 2-го ранга от функции 3-го.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Чтобы определять числовой ранг функции, у нас не хватает источника. В доках по хаскелю не объяснено, как по сигнатуре определить ранг.

Стас говорил, что определение ранга непростое, и мы подумали, что оно на практике не нужно. Достаточно отличать первый ранг от всех остальных, а уж какой он - третий или четвертый - не влияет на то, как применять RankNTypes.

* Give examples of rank-1, rank-2, rank-3 functions.
* What is the main goal of `RankNTypes` extension?
* Can we create datatypes and newtypes with `RankNTypes`?
Expand Down Expand Up @@ -197,17 +197,18 @@
* `1:(thunk)`
* `1:2:(thunk)`
* `1:2:3:[]`
* `thunk:thunk`
* `15`
* `\x -> x * 2`
* `(\x -> x + 1) 3`
* Can haskell evaluate in strict mode?
* Why strict functions in Haskell evaluate values to WHNF and not NF?
* What is the function `seq` (and operator `$!`)?
* What is the function `deepseq` (and operator `$!!`)?
* Could using `seq` change the returned value of the function?
* What is the expression result: ``(a + b) `seq` ((a + b) : list)``? Why?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Не очень понятно к чему относится второй вопрос Why?, может его раскрыть?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Вопрос, почему результат именно такой, какой он есть :). Why does it happen? - может так?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is it?

Copy link
Contributor

@evgeny-osipenko evgeny-osipenko Dec 23, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Грамматическая придирка - в текущем виде, кодовая цитата относится к слову "result", то есть вопрос буквально звучит как "Какой у выражения результат: (a+b) `seq` ((a+b) : list)". Я думаю, будет более верно сформулировать как "What is the result of the expression: <>".

А вообще, мне не совсем понятно, что именно ожидается в ответе на этот вопрос - ну, результатом будет (a+b) `seq` ((a+b) : list), duh. Ну, можно переписать это как let x = a+b in x `seq` (x:list) Может, лучше вообще спрашивать не про "результат", а про поведение в конкретных ситуациях - под evaluate и evaluateNF, если в a боттом, если в a стоит trace или unsafePerformIO, если на результат ещё сверху повесили trace или unsafePerformIO, и продвинутый вопрос - если мы в реализации (+) впишем trace или unsafePerformIO.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

С придиркой согласен, переделаю.

Насчет ответа на вопрос: да, здесь вопрос скорее о поведении, а не о результате - что в этом выражении seq бесполезен, и надо объяснить почему. Кстати, источника не хватает.

а про поведение в конкретных ситуациях - под evaluate и evaluateNF, если в a боттом, если в a стоит trace или unsafePerformIO, если на результат ещё сверху повесили trace или unsafePerformIO, и продвинутый вопрос - если мы в реализации (+) впишем trace или unsafePerformIO.

Про evaluate не понял. Про unsafePerformIO пусть отвечающий рассказывает в вопросе про то, может ли seq изменить результат выражения :). Там прямо напрашивается. Или можно явно спросить об этом, но мне кажется, изначальный смысл вопроса был в другом.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Поправил вопрос, но так и не нашел источник, где я видел ответ. Может, потом. Вы знаете ответ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Если referential transparency соблюдается - то выражение семантически эквивалентно let x = a+b in x `seq` (x:list). По факту - компилятор имеет полное право как объединить одинаковые выражения, так и оставить их раздельными.

let a = unsafePerformIO (print "A" >> pure 1)
let b = 2
let z = (a + b) `seq` ((a + b) : list)
print "Start"
zh : _ <- evaluate z
print "Mid"
void (evaluate zh)
print zh
print "End"

На код выше компилятор может написать как Start // A // Mid // A // 3 // End, так и Start // A // Mid // 3 // End - допустимы оба варианта. Скорее всего, GHC будет работать по первому с -O0 и по второму с -O2.

* What is the GHC extension `BangPatterns`?
* Make examples when bang pattern is useless.
* Make examples when bang pattern has less power, than it could be supposed.
* What form does the bang pattern force values to be calculated to?
* Show the difference between this two definitions:
* `f1`

Expand All @@ -223,14 +224,16 @@
f2 x False = False
```

* Does bang patterns force execution, when they are nested in constructors inside of `let` or `where` expressions?
* There is a `!` inside a `Maybe`, which is inside a `let` expression, and `let` expressions are lazy:
* Do bang patterns force execution when they are nested in constructors inside
`let` or `where` expressions? Does this force `a` to be evaluated and when
it does?

```haskell
let (Just !a) = x in 1 + 1
```

* What are the GHC extensions `Strict` and `StrictData`?
* What form do Haskell functions calculate values to with `Strict` extension enabled? Why not to another form?

#### Resources

Expand Down