
Женя Зэ
14.05.2017
05:25:08
Я мимокрокодил, вобщем-то

Илья
14.05.2017
05:25:15
У них суппорт вообще есть?

Женя Зэ
14.05.2017
05:25:47
Не знаю, обхожу иде стороной по возможности

Google

Evgeniy
14.05.2017
05:37:19
@DarkByte2016 Запускай через mono, это рекомендованный способ.

Илья
14.05.2017
05:37:36
я вот никак не пойму как работает вывод типов в F#. Например
let main args =
как оно определяет что args это string[] ?

Evgeniy
14.05.2017
05:39:19
По аннотации [<EntryPoint>].

Илья
14.05.2017
05:39:21
mono app.exe
или это типа дефолтное поведение и его можно переопределить вручную указав типы?

Evgeniy
14.05.2017
05:44:34
@DarkByte2016 Если функция нигде не используется, то он выводит по-дефолту неиболее подходящий вариант. Например, если ты потом напишешь, add 2.0 2.0, то компилятор выведет тип float -> float -> float. Но функция перестанет работать для int.
Если ты хочешь функцию ad-hoc перегрузить для разных типов, то тебе нужен inline.

Илья
14.05.2017
05:45:17

Evgeniy
14.05.2017
05:45:39
Сравни типы у let add x y = x + y и let inline add x y = x + y.

Илья
14.05.2017
05:47:18

Google

Илья
14.05.2017
05:47:37
круто че, оно типо сразу запрашивает аргументы у которых есть эта операция

Evgeniy
14.05.2017
05:47:58
Да. Она теперь будет работать для всех типов, у которых плюс перегружен.

Илья
14.05.2017
05:51:35
а почему тут используются двойные точки с запятой? ;; почему не одинарные как везде?))
и вообще насколько я понял они не везде нужны же?

Friedrich
14.05.2017
06:01:18
В .Net билды не завязаны на платформе
Это не совсем верно:
- self-contained deployment всегда платформозависим, потому что он с собой тащит платформенную версию рантайма
- любой деплоймент может оказаться платформозависимым, если ты тащишь нативные либы (и необязательно ты сам — бывает, что транзитивные зависимости нативные)

Klei
14.05.2017
06:03:35

Илья
14.05.2017
06:04:06

Klei
14.05.2017
06:04:35
FSharp Interactive.

Илья
14.05.2017
06:04:42
аа

Friedrich
14.05.2017
06:06:19

Илья
14.05.2017
06:06:36

Friedrich
14.05.2017
06:08:04
Простой запуск экзешников работает за счёт специального расширения ядра (?), которое инициализируется вместе с установкой Mono, но
1) это не всегда удобно (как в твоём случае)
2) это не на всех машинах работает (потому что не у всех это расширение есть)
Я бы шеллскрипт написал, назвал его так же, как приложение, но без расширения (например, вместо myfsharpapp.exe он бы назывался myfsharpapp), а в нём вызывал mono с именем экзешника.

Илья
14.05.2017
06:19:46
в rider есть fsi?

Igor
14.05.2017
06:22:16

Летучая
14.05.2017
07:57:51
Язык же идентовый

Friedrich
14.05.2017
07:58:28
В REPL нужны :(
А в коде не нужны, да. Вообще нигде их не ставлю.
Более того, обычные точки с запятой тоже можно не использовать в большинстве случаев (или даже во всех). Вместо [1; 2; 3] можно писать
[1
2
3]
(другой разговор, что это не всегда красиво выглядит, но если элементы списка длинно записываются — тогда имеет смысл)

Google

Илья
14.05.2017
08:14:41
еще такой вопрос: вот например есть функции модуля List, типа List.length, а можно как-то сделать чтобы не писать все время название модуля? я так понимаю там статические функции, можно ли сделать как в C#
using static List;
типа того
и писать потом просто length

Friedrich
14.05.2017
08:15:55
Для некоторых модулей работает просто open ModuleName, но не для List.

Илья
14.05.2017
08:16:18
жаль( так длиннее

Friedrich
14.05.2017
08:16:19
Потому что ты очень быстро заблудишься потом, где у тебя List.length, а где Array.length, например.

Илья
14.05.2017
08:17:00
т.е. если на входе массив то юзать Array.length, а если список то List.length

Friedrich
14.05.2017
08:18:43
Да.

Илья
14.05.2017
08:19:46
Да.
Да - может? А почему тогда так нельзя сделать?)))

Friedrich
14.05.2017
08:20:27
А, ой, прости, я не полностью прочитал сообщение. Да, для списков одна функция, а для массивов — другая :)

Илья
14.05.2017
08:21:05

Friedrich
14.05.2017
08:21:15
Ты можешь сделать свою функцию, которая будет без оверхеда работать для всех нужных тебе контейнеров. Но в стандартную библиотеку такой функции не завезли.

Илья
14.05.2017
08:21:15
Недоделка языка?
понятненько

Friedrich
14.05.2017
08:21:58
Недоделка языка?
Кто-то это считает недоделкой, а кто-то — грамотным решением. Перегрузки функций по типам аргументов в F# нет.

Илья
14.05.2017
08:22:20
офигеть...

Friedrich
14.05.2017
08:22:43
Да, серьёзно. Перегрузка есть только в методах классов, а в обычных функциях нету.

Илья
14.05.2017
08:23:53
Или там только все на обычных функциях?

Google

Friedrich
14.05.2017
08:24:14
В ФП под "классами" могут начать понимать что угодно :)
Кто-нибудь может "классом" называть класс типов или интерфейс.
Но в F#-коде использование C#-классов или структур не возбраняется.

Илья
14.05.2017
08:25:09
класс это объявление с ключевым словом class, судя по автодополнению в райдере оно в F# есть

Friedrich
14.05.2017
08:25:32
Оно не всегда вписывается в "функциональный" дизайн, но если аккуратно пользоваться — то никаких проблем не будет.

Летучая
14.05.2017
08:25:51
Но зачем

Илья
14.05.2017
08:25:52
понятно, эдакий императивный костыль

Летучая
14.05.2017
08:25:59
Если есть type с плюшками

Admin
ERROR: S client not available

Летучая
14.05.2017
08:26:15
И где у тебя длинный код получается

Friedrich
14.05.2017
08:26:16

Летучая
14.05.2017
08:26:40
seq
|> List.concat
зато понятно, какой тип на выходе

Friedrich
14.05.2017
08:27:12

Летучая
14.05.2017
08:27:21
ну вот

Илья
14.05.2017
08:27:23
а List это не класс? это типа просто название библиотеки содержащей обычные функции чтоли?

Летучая
14.05.2017
08:27:28
модуль это

Friedrich
14.05.2017
08:27:50

Илья
14.05.2017
08:27:51
понятно)

Friedrich
14.05.2017
08:28:23
Соответствующий тип называется list.

Google

Илья
14.05.2017
08:28:38
погоди, но зачем надо Array.length если можно сделать args.Length ?)))
массив это же объект

Friedrich
14.05.2017
08:28:52
(но я не уверен; возможно, у него есть и какое-нибудь C#-friendly название типа FSharpList<T>)

Илья
14.05.2017
08:30:41

Летучая
14.05.2017
08:31:31
.Length не только у массива может быть
это свойство

Friedrich
14.05.2017
08:31:39
Потому что вот представь, что компилятор видит такое определение: let myLen f = f.Length
Что ему про это определение подумать? Какой тип здесь имеет f? Ведь есть бесконечно много типов с таким свойством.

Илья
14.05.2017
08:32:18
хмм а если так?
let a (ar: Array) = ar.Length
вроде компилится

Friedrich
14.05.2017
08:33:24
Ну, именно так не получится, потому что Array это не тип а какая-то фигня :)
А вообще — да, если компилятору подсказать тип, то всё заработает.

Илья
14.05.2017
08:34:26
ну если он сам не можете сообразить какой тип юзать)))

Friedrich
14.05.2017
08:34:59
Работает любой из этих вариартов:
let len (x : 'a array) = x.Length
let len (x : 'a[]) = x.Length
Кстати, я лично у себя всегда на границах модулей сам указываю типы. Это помогает себя дисциплинировать, и нечаянно не сломать публичный API.
А для приватных функций или каких-то внутренних — не указываю.

Nikolay
14.05.2017
08:50:02

Vasily
14.05.2017
08:50:19
интересно наблюдать за ходом мысли новичков :)

Nikolay
14.05.2017
08:50:25
Но в статик типах можно перегрузки использовать
Я до сих пор полностью красивого и лаконичного решения для своей либы не нашёл :(

Pavel
14.05.2017
08:56:44
Ну я бы с удовольствием имел перегрузки bind для всех монадных классах. В хаскеле пишут >>= и не имеют проблем, к сожалению в F# так нельзя, и я не назвал бы это каким-то специальным решением.