人類には早すぎる、謎の計算ロジックに立ち向かう / Strugle with the most complicated logic ever
タグ検索の該当結果が少ないため、タイトル検索結果を表示しています。
純粋関数型プログラミングで副作用を扱う方法Posted by Mizunashi Mana on April 05, 2020 Haskell は他のプログラミング言語には見られない特徴を多く持っている。その中の1つが純粋性だ。Haskell は純粋関数型プログラミング言語であることを、売りの1つにしている。しかし、純粋性は多くの場合表現力の縮小を招く。ところが Haskell は、IOモナドの導入により、通常のプログラミング言語と変わらぬ表現力を持てるようになっている。これは、とても驚くべきことだ。しかし、同時にこれは Haskell 入門者にとって、大きな混乱を招いているようだ。 今回は、そもそも純粋性とはなんなのか、なぜ他の言語は純粋性を担保できないのか、そして Haskell はどうやって IO モナドにより純粋性を担保しつつ他の言語と変わらない表現力を持てるようにしているのかにつ
Haskell製の新しいメッセージングシステムfranz(フランツ)の紹介。 github.com 背景 取引所にあるマシンで取引プログラムを実行するのが我々の仕事だが、朝8時に起動したらあとは昼寝したり酒を飲んだりというわけにはいかない。モニタリングしたり、分析のためにデータを残しておく必要がある。そのため、プログラムによって解析しやすい形でログを出力する。 今までは複数の種類のレコードをシリアライズし、一つのファイルに連結させる独自のフォーマットを10年近く使っていたが、書いていて恥ずかしくなるような多数の問題を抱えていた。 柔軟性が乏しい: 32bit整数や文字列などの単純な値しか格納できず、例えばレコードを含むレコードなどを表現できない。その結果、複雑なデータは一旦文字列に変換するような運用がされており、そのプリティプリンタやパーサは十分にテストされていない。 コードがまとまってい
プログラミング言語が2-圏として考えられるということについてソースから訳出した。(2023.2.22) 動機 最近、chatGPTにいろいろ尋ねるのが流行っているらしい。Haskellで有名なモナドの概念がなぜ導入されたか尋ねている人を見かけて、そういやそういう記事見たことないなと思ったので適当に調べた。 一次ソース 元ネタは以下のマイナーだと思われる文献 An abstract view of programming languages Eugenio Moggi教授のあんま読まれてない方の論文 Denotational Semantics Peter D. Mosses教授のこの論文(2部あって後半の方) 邦訳があり邦訳で読んだ。 プログラミングのモナド発見の経緯 プログラミングのモナドはなんか包んだり抜き出したり見たいな感じの概念で知られてますが、プログラミングの概念をモジュール化す
Haskellは関数型プログラミング言語と呼ばれますが、関数だけでなく型も重要な役割を担っています。アルゴリズムを考える時、手続きの最適化だけでなく、正しいデータ型を選択することがシンプルなアルゴリズムを導き、実装をコンパクトにできるというのはよくある話です。今回は非常に単純な型でありながら幅優先探索というアルゴリズムのエッセンスを詰め込んだ Levelsというデータ型 について紹介したいと思います。 ピタゴラス数を列挙する ピタゴラス数とはピタゴラスの定理における関係式 a^2 + b^2 = c^2 を満たす自然数の三つ組です。 Haskellのリストは遅延評価なので 全ての自然数の三つ組を列挙する 列挙した自然数の中から関係式を満たすものだけ抽出する という手順でピタゴラス数を列挙することを考えてみましょう。 実際この方法は有限な探索範囲ではうまく機能します。 pyth :: [(I
この記事は言語実装Advent Calendar 2020 25日目の記事です。(2022-11-06: 記事の内容を追記していますが、この記事の結論としては「似たようなものは作れるが、完全体にはならない」です) 前提知識 高階カインド型 モナド 従来のエミュレーション方法 Generic Associated Types を用いたエミュレーション(new!) 型クラスを定義する Functor を用意する Pointed を用意する Applicative を用意する Monad を用意する いくつか型を実装していく 現状実装できないもの do 記法 Generic Associated Types(GATs)とは何か 追記(2022-11-06) リポジトリ 参考文献 モナドに関する話題が言語実装アドベントカレンダーの範疇に入るのかわかっていませんが*1、プログラミング言語がお好きな方
Abstract 本セッションの目的は、ずばり モナド (monad) に対する 初心者の心理的障壁を取り除くこと です。モナドはプログラミング言語 Haskell と関連して言及されることが多く、世間では何か得体のしれない難解な概念だというイメージが先行しています。しかし、実際にはどのプログラミング言語にもある「処理」の概念を一般化しただけで、プログラマにとっては顔見知りの相手に過ぎません。 本セッションでは、実際の使用場面から逆算してモナドを再発明することでその必然性を体感し、必要以上に強調された神秘性を引きはがすことを目標とします。受講後には、セッション内で扱わなかった Haskell の基本文法を少し補うことで、モナドを利用した単純なプログラムならすぐに書けるようになるでしょう。 そもそも、なぜモナドや、それを用いる Haskell にはこんなにも怖ろしげなイメージが先行しているの
この投稿は、Haskell Advent Calendar 2019 の4日目の記事です。STモナドの仕組みについて書きました。初中級者向けの内容となっています。 はじめに STモナドとは STモナドの型 STモナドの使用例 STモナドで使用されるデータ型と各種関数 Data.STRef newSTRef modifySTRef readSTRef runST 変更可能な参照を外へ持ち出そうとすると エラーメッセージから考察する forallの探求 量化子は型に量的な意味を持たせる 量化子を関数の内側で定義する ランクN多相の概要と特徴 ランクN多相の概要 特徴その1: 型推論の制限を緩和 特徴その2: スコープ内での型の束縛 forallの探求はここで終わり STモナドのトリック newSTRefの結果型の意味 runSTの引数の型の意味 おわりに 訂正内容(2019/12/06) 参考
はじめに Haskellは静的純粋関数型プログラミング言語と言われるジャンルの言語であり、型や状態に厳しくWeb開発に向いていないと思われる方が多いと思います。 しかし 型の力によるクリーンアーキテクチャ 抽象化による高級な記述 圧倒的な型推論による軽量言語のような書き心地 意外と高いシングルスレッド性能 パフォーマンスも非常に高く, 書きやすい並行並列処理 上記のような利点があり、実はWeb開発に非常に有用な言語であると思っています。 HaskellでのWeb開発における標準的なインターフェースであるwai(web application interface)、そのインターフェースのアプリケーションを動作させる標準的なサーバーであるwarpという二つのライブラリを用いてボトムアップでWebアプリを作っていき、徐々に応用させていこうと思います。 waiとwarpはHaskellのWeb開発
タイトルで全部言い切ってますが // Optional container like maybe monad class Option { constructor(value){ this.value = value } async promise() { return new Promise((resolve, reject) => { if (this.value) { resolve(this.value); } else { reject(undefined); } }); } } こんなMaybe とかOptionalっぽいやつを用意します。 promise() で Promiseを生成して返すようにします。もってる値に応じて resolve (JustやSome)したり reject (Nothing)したりします。 const o1 = new Option("foo");
前回の記事は魔法のように見えるStateモナドの実装も、順を追って見ていけば理解することは難しくないという話でした。 しかし状態の変更を順番に処理するというような手続き的な考え方にかなり近い構造が、うまくモナドになってくれるというのは少し不思議ですよね。 この記事では タプル (a, b) 関数 a -> b カリー化 curry :: ((a, b) -> c) -> a -> b -> c uncurry :: (a -> b -> c) -> (a, b) -> c といったHaskellの基本的な要素が随伴と呼ばれる関係を構成することを見て、 その随伴からStateモナドが導かれることを説明していきたいと思います。 随伴 二つの圏 C, D と二つの関手 F : C \rightarrow D, G : D \rightarrow C が与えられたとしましょう。 もし GF = {
◆ エンジニア業務環境アンケート結果 ◆ エンジニアが自分の働き方にどういったことで満足していて、不満を感じているのか、働きたい会社像として何を求めているのか、業務環境調査を実施しました。ぜひご覧ください。 ⇒ アンケート結果はこちらから はじめにこんにちは、SIOS アプリケーションコンサルティングGの池田 透です。 この記事ではTypeScriptのfp-tsという関数型プログラミングのためのライブラリを使ってモナドについて説明してみます。 モナドに関する説明は数多くありますが、とても高尚な概念の説明だったり、逆にマニアックにモナドのテクニックを説明するものが多くとっつきにちょうど良いものがなかなかないんですね。 そこでTypeScriptでプログラミングをしていたらモナドを使いたくなる(かもしれない)例を使って動機付けしながら説明していきたいと思います。 tl;dr商品IDと数量から
Haskell の IO モナドって,中身どうなってたんだろと気になってて,ちょっと調べてみた.そのメモ. IO モナドと RealWorld まずは基本から. IO モナドは, Haskell の根幹となるモナドで, main も IO で書く. GHC では中身は次のように定義されている [1]: -- In GHC.Types module of ghc-prim package newtype IO a = IO (State# RealWorld -> (# State# RealWorld, a #)) 見ての通り, IO a は State# RealWorld -> (# State# RealWorld, a #) の newtype だ.あんまり見慣れない State# RealWorld という型と (# , #) という型が出てきたけど, State# RealWo
2020.04.07 週刊Railsウォッチ(20200407後編)RubyのTracePointでデバッグ、Rubyとモナド、Gitノウハウ集、リモートワークほか こんにちは、hachi8833です。リモートワークでは、高品質のマイクの他に高品質の椅子も重要ということが判明しつつあるようです。 各記事冒頭には⚓でパーマリンクを置いてあります: 社内やTwitterでの議論などにどうぞ 「つっつきボイス」はRailsウォッチ公開前ドラフトを(鍋のように)社内有志でつっついたときの会話の再構成です👄 毎月第一木曜日に「公開つっつき会」を開催しています: お気軽にご応募ください ⚓Ruby ⚓TracePointで変わるRubyのデバッグ 元記事: Changing the Approach to Debugging in Ruby with TracePoint | AppSignal B
Haskell Advent Calendar 2019 5日目 この冬、神速のサンタクロースがやってくる—— Haskellにおいて、バイト列の表現はByteStringが定番である。ByteStringはPinned領域に直接格納され、空間効率はリストに比べればはるかに良い。しかし、Pinned領域にあるとヒープフラグメンテーションが起こりやすくなるということでもあり、細かい文字列をつなぎ合わせるような使い方はパフォーマンスに悪影響が及ぶ。そのような問題を避けるため、ビルダーと呼ばれる構造が用意されている。 Data.ByteString.Builderは、word8 42 <> byteString "hello" <> doubleLE 42のように細かいプリミティブを連結し、toLazyByteStringを呼ぶと最後にByteStringを一気に鋳出せるという仕組みである。By
はじめに 近頃の for 文は、コレクションの要素を直接参照できたり、 yield で評価結果を返せたり、多重ループを一気に回せたり、便利なものが多いですね。たとえば Scala であれば、こんなふうに書けます。 val list = for { a <- List(100) b <- List(10, 20) c <- List(1, 2, 3) } yield a + b + c print(list) // List(111, 112, 113, 121, 122, 123) この for 文のみを頼りに、ときおり関数型プログラマが唱える「モナド」に入門してみよー、というのが本記事の趣旨です。 なるべく簡単なコードを挙げながら、できるだけ「圏論」の各種定義やその気持ちまで掘っていくので、前提知識なしで読みすすめられると思います。 Scala の for 文 まずは Scala 使いで
今まで不満の多かったHaskellのレコードの扱いを改善するための一歩として、NoFieldSelectorsというGHC拡張の実装を進めている。 動機 Haskellにはレコードを定義するための構文がある。 data User = User { userId :: Int , userName :: Text } こう定義すると、各フィールドごとにuserId :: User -> IntとuserName :: User -> Textというゲッターに相当する関数が生成される。これらの関数は特別な意味合いを持っており、以下のレコード操作の構文にも利用できる。 構築 User { userId = 0, userName = "Zero" } パターンマッチ case foo of User { userId = x, userName = name } -> ... 更新 foo {
2020.08.17 週刊Railsウォッチ(20200817前編)お盆も続くRails改修、Rails 6.1にManyモナドが入る?rails-auth gemでクライアント認証ほか こんにちは、hachi8833です。皆さま熱中症にはお互い気をつけましょう。 参考: 熱中症を防ぐためには(環境庁PDF) つっつきボイス:「昨日急に体調つらくなって、自分でもびっくりするぐらい丸一日寝てたんですけど、もう一日の記憶がありませんし😇」「これだけ暑いと冷房の効いた部屋にいても体調悪くなりそうですよね…」「いやホントお大事に💊」「ウォッチも熱中症対策ということでエントリを減らし目にしました」 私も猛暑になるととりあえず梅干ししゃぶってクエン酸補給してます。 「そうそう、『室温28℃はエアコンの設定温度ではありません』ってよく注意喚起されてますよね」「自分はとりあえずエアコン27℃にしてます
qiita.com C++、Rust、Pythonなど、他の言語では当たり前のように多用される動的配列だが、Haskell実装は(開発を始めた時点では)見当たらなかったので作ってみたお話*1。 動的配列とはミュータブルな配列の一種で、通常の配列操作だけでなく、末尾への要素の追加・削除が定数時間で行える構造である。確保しておいた領域がいっぱいになったら、その2倍の大きさの領域を確保するという方法によって、漸近的には要素の追加は定数時間となる。 内部の配列には、デファクトスタンダードであるvectorパッケージを用いる。Vectorには無印(boxed)、Unboxed、Storableの三種類の変種があり、それぞれ以下のように使い分ける。 無印(Data.Vector): サンク含め、任意のHaskellのオブジェクトを格納できる。Traversableなどのインスタンスであり、汎用性が高い
TL;DR github.com 並行処理を簡潔かつ安全に記述できるライブラリを作った。ApplicativeDo拡張を使って、以下のようにoathの引数として与えたIOアクションを同時に実行し、結果を集める処理を書ける。いずれかが例外を投げた場合、残りをキャンセルするためリソースを漏らす心配がない。 evalOath $ do a <- oath $ ... b <- oath $ ... f a b 経緯 Haskellは並行処理が得意とされている。事実、軽量スレッド、MVar、STMといった処理系によるサポートが充実しており、HackageのConcurrencyカテゴリには235ものパッケージがあることからもユーザの関心の高さが窺える。 並行処理を実用する上では、単にスレッドをフォークするだけでなく、計算の結果を集める必要がある──Scalaなどで言うFutureに近いものがあると
ミーハーな読者なら、barbiesというライブラリをご存知の方も多いと思う。そう、HKDを扱う定番ライブラリだ。HKDは、同アドベントカレンダーにも寄稿されている他、Haskell Dayでも紹介された(https://assets.adobe.com/public/b93f214d-58c2-482f-5528-a939d3e83660)注目の技法だ。Higher-Kinded Data (HKD) について - Qiita HKDは、一番簡単な場合であるはずのIdentityを使うと着脱が面倒になるという問題がよく知られている。Data.Barbie.BareモジュールのWearという型族を使って定義すれば、それを簡単にはがせ、普通のレコードと全く同じように使える。 data Barbie t f = Barbie { name :: Wear t f String , age ::
関数をデバッグするために、引数と戻り値をそれぞれ表示するというのを誰しもやったことがあると思う。今回はそれを自動化するからくりをHaskellで実装してみる。 目標となるのは、関数が与えられたとき、その引数と結果をターミナルに出力する関数に変換する高階関数、probe :: Traceable a => String -> a -> aである。 testDelay :: Double -> Double -> IO () testDelay dur dur' = threadDelay $ round $ (dur + dur') * 1000000 *Probe> probe "testDelay" testDelay 1 2 testDelay 1.0 2.0: () これは型クラスを活用すればお茶の子さいさいである。以下のように型によって挙動を切り替える関数withTraceData
Rust1.74でモナドを作ってみようとしてたのですが、今回はその続きになります。 なんで続きをやろうと思ったの? Rust1.74で導入された以下の機能を使って、モナドを作ろうとしたのですがその時は残念ながらできませんでした。(詳細はこちらを参照ください。) その時は、traitの中で -> impl Traitをすることができなかったので断念したのですが、Rust1.75で導入された以下の機能を使えばできそうに見えました。 そのため、この機能を使って再チャレンジしようとしたのがこの記事になります。 この機能で何ができるようになるのか 詳細は上記blogを見ていただくとして、ざっくり説明すると、Trait内で-> impl Traitを定義することができるようになります。 上記blogからの引用ですが、こんな感じです。 trait Container { fn items(&self)
GitHubのプロフィールを見た人などはもしかしたら気づいているかもしれないが、Tsuru Capital LLCを退職し、2022年2月16日よりHERPの正社員となった。HERPは、大まかに言えば採用活動を管理するプラットフォームを提供している。 きっかけ Tsuru CapitalはKospi(韓国株のインデックス)のデリバティブを半自動取引する企業で、Haskellを使っているというのが最大の特徴として知られる謎多き会社だ。2015年に入社し、2022年まで6年以上働いた。流石に同じ職場にずっといると経験が偏ってしまうし、感覚としても飽きがきたので転職を考えた。 また、ある時期からRustメインの開発をするようになったが、やはり自分の最大の強みであるHaskellを活かせる仕事をしたく、転職先を考える基準となった。 拙作のライブラリであるextensibleを使っているという情報も
この記事は NSSOL Advent Calendar 2022 の1日目の記事です はじめに 私が現在所属しているチームでは、フロントエンドもバックエンドも共にTypeScriptをで開発を進めており、具体的にはフロントエンドではReact、バックエンドではNestJSを使用しています。 TypeScriptで共通化させることで、TypeScriptが提供する型安全性を享受しながらも、バックエンドとフロントエンドで大きなコンテキストスイッチを発生させることなく開発を進めることができていると感じています。 ただ、実感としては、バックエンドではソフトウェアで解決したい対象となるドメインのモデルを class で表現したり、フロントエンドのReactでは小さい関数や hooks を集約させることでロジックを表現したりと、フロントエンドとバックエンドでのロジックの構築方法に差異を感じていました。
今回の目的 今回はモナドの厳密なルールより、なぜ使うのか?どう使えるのか?を簡単なところを数学表現なしでまとめてみるのが目的です。 まだまだモナドを完全に完全理解した! とはいい難いのですが、現在までの理解を書いてみたいとおもいます。 関数型プログラミングに関する熱い話はこちらの記事が参考になります! 関数型言語のウソとホント 関数型を考える上での前提 - プログラミングの作用と副作用 プログラミングの入力と出力は関数の引数と戻り値がメインです。 「作用」とは、その引数に対しての戻り値のことです。 Webアプリケーションサーバでの作用の考え方 HttpのリクエストのデータをHttpのレスポンスデータに変換する処理に過ぎません。 Scalaで表現するとこんな関数定義です。 val func : HttpRequest => HttpResponse Scalaでは => は関数の定義を示しま
21世紀現在のプログラミング言語において、モジュールという機能はほぼ必要不可欠である。ソースコードを分割し、明示的な依存関係を指定する仕組みであるモジュールは、以下のような様々な恩恵をもたらす。 インクリメンタルビルド: モジュールごとにコンパイル結果を保存し、変更されていない部分を再コンパイルするのを防ぐ。 内部の隠蔽: 実装の詳細を隠蔽し、モジュール外から触れないようにする。プログラムの見通しをよくしたり、不正な操作をする機会を減らす。 アーキテクチャの整理: モジュールは他のモジュールを参照できるが、原則として相互参照はしない。依存の向きを定めることで、適切な抽象化と、 それに基づいた実装の分離を促す。 さて、いくらモジュールが便利と言えど、数が増えすぎるとさすがに扱いにくい*1。そのため、ディレクトリの構造をモジュールの階層構造として運用する仕組みが備わっていることが多い。 コンパ
C++ Advent Calendar 2022 の 3 日目の記事 を読んだのですが、C++の規格を作っている人の中にモナドが好きな人がいるようで、仕様書の中にモナド的などという単語を必要もないのに入れようしているようです。それでモナドに興味を持った人もいるかと思って記事を書いてみることにしました。巷にモナドの説明自体はいっぱいあるんですが、Haskellを使って説明するものばかりで読みにくいですし、なんだか要領を得ないものが多いので、C++で説明する需要はあるだろうと思っています。ただし、C++でモナドを作っても意味がないよという否定的な意見を書きますので、そういうのがお好みでない方は許してください。 シンタックスシュガーがないのに、モナドを作るんですか? とりあえず説明のために簡単なIOモナドっぽいのものを書いてみます。まず、文字列を表示する動作を次のように書けるようにします。これは
なぜモナドが重要なのか? 私たちは関数のみを使ってプログラミングしたい。(つまるところ「関数型プログラミング(FP)」) なぜモナドが必要なのか? - Qiita しかし非決定的な計算・副作用を伴う計算などなど、関数でどう扱えばいい? モナドは値およびその値を使う計算の並びという観点からいえば、計算を構造化する方法です モナドのすべて - イントロダクション 非決定性・副作用・例外処理など全部モナドで構造化された計算として表してしまえばいい! (そしてそれが可能である!) それが良いかどうかは別として、純粋さをとことん追求した必然の孤高の帰結がモナドというわけです モナドはなぜHaskellでしか積極的に使われていないのか? - uehaj's blog 最近はasync/await等よく似た機能が他の言語にも徐々に取り入れられている 増え続けるモナドチュートリアル プログラミングにおける
Freeは、Functorを受け取ってMonadをつくることができるモナドです。 Freeのデータ型の定義は以下です。 よくわからない再帰的な定義がされていますね。初見で読めたらすごいと思います。 この記事では、上の定義のようなFreeがどのようにMonadをつくるかを見ていきます。 次のような順で説明していきます。 PureScriptの予備知識と用語説明 ListについてFunctor / Monadを実装する Free fについて、同じようにFunctor / Monadを実装する Free fだけでなく、Freeそれ自体もモナドではあるんですが、1つ高いレイヤー(誤魔化した言い方)でのモナドなのでこの記事では触れません。 PureScriptの型システムでは表現できないですしね。 忙しい人のためのFree この記事で説明したいことをひとことで言うと、 Pureがpure、Freeが
JavaScriptにおいて、Promiseのthenを使った書き方を、async/awaitを使って書き換えられるわけですけども その書き換えって、Haskellのモナドでbind(>>=)を使った書き方を、Do記法に書き換えとそっくりじゃないですか? ということで、どんな感じで対応しているか検証してみます。 コードの全文は最後に載せますね。合わせて60行もないです。 Haskell側のモナドとして、Eitherモナドを使うことにします。 Haskellのコードはimport Data.Eitherしておきます。 記事を通して使う関数 まずは、Promiseやモナドを返す関数ohとyeahを用意します。
突然ですが、Stateモナドの実装を書けますか? Stateモナドは自由に読み書き可能なグローバル変数のような機能を、副作用を伴わない純粋な関数だけを使って実装するための便利な概念です。使うだけなら簡単なので普段から便利に利用してる人も多いかもしれませんが、いざ自分で実装しろと言われると手が止まってしまう方もいるのではないでしょうか。 今回はそんなStateモナドの実装を丁寧に見ていき、仕組みを理解することを目指したいと思います。 State さっそく以下に示すのがStateモナドの型の定義です[1]。 まずStateはnewtypeを使って関数と同じ型として定義されます。この関数は以下の構造を意識して作られています。 実行前後で状態の型は変わりませんが、値に関しては変更することが可能になっているのです。 モナドにするためにはFunctorとApplicativeのインスタンスにする必要が
j次のブックマーク
k前のブックマーク
lあとで読む
eコメント一覧を開く
oページを開く