VisualStudio を使って Mac で F# の始め方(MSの資料の抄訳)

以下は,Microsoftのこちらのページ(Get started with F# in Visual Studio for Mac)の抄訳。原文は2017年2月13日版。

Visual Studio for Mac IDEは,F# および Visual F# をサポートしている。まずVisual Studio for Macをダウンロードする。この文書は,Visual Studio Community 2017 for Mac を使うことを前提にしている。

F#のインストール

Visual Studio for Mac のインストールでは,F# そのものは,初期設定のままでサポートされているので,特に何かをする必要はない。

コンソールアプリケーションの作成

Visual Studio for Mac で最も簡単なアプリケーションは,コンソールアプリケーションであるので,以下にその作成方法を示す:

  1. ファイルメニューからNew Solution を選択。
  2. New Project dialog が現れ,コンソールアプリケーション用には二種類のテンプレートが表示される。一つは,Other -> .NET にあり, .NET Framework である。もう一つは, .NET Core -> App にあり,こちらは .NET Core を想定している。この文書で書かれている内容に限っては,どちらを選んでもよい。console app を選ぶ際, C# から F# に切り替えてあるか,確認すること。
  3. プロジェクトに名前を設定し,必要なオプションを選択する。オプションの選択に応じて,プレビュー欄に表示されるディレクトリ(フォルダー)構造も変化する。
  4. Create をクリックして完了。F#プロジェクトがソリューションエクスプローラ内に表示される。

コードを書く

Program.fs という名前のファイルを開き,その中身を以下のように書き換えよう:

module HelloSquare

let square x = x * x

[<EntryPoint>]
let main argv =
    printfn "%d squared is: %d!" 12 (square 12)
    0 // Return an integer exit code

上記のコード例では, square 関数は x という引数を一つとり,それを自乗する関数として定義されている。F# は 型推論をするので,x の型を明示しなくともよい。F# コンパイラは,掛け算がどのような場合に有効であるかをわかっているので, square がどのような条件で呼び出されるかという情報を元に,x に適切な型を割り付けることができる。 square 関数名の上にマウスを動かすと,以下の情報が表示されるはずである。

val square: x:int -> int

これは,関数の型シグネチャである。意味するところは,「square は,整数型の引数 x をとり,整数型の結果を出力する関数」である。 square が int を出力すると特定されているのは,掛け算が特定のいくつかの型のみに有効な演算だとコンパイラがわかっているので,このことをもとに,この時点では int を選んでいる。だが,引数の型を別の型,例えば float に変えたとしたら,関数の型シグネチャも自動的に変わる。

別に,main 関数が定義されているが,これは EntryPoint 属性により,F#コンパイラはプログラムの開始位置をここからだと認識する。以下,コマンドライン引数がこの関数に渡され,返り値として(典型的には 0 なのだが,)整数値を出力するC言語タイプのプログラミング言語の作法に則った記述が続いている。

上記の例では,square 関数を呼び出すにあたって,引数に 12 をあてている。F#コンパイラは,これをもって square の型を,int -> int (つまり,この関数は int 型の引数を一つとり,int 型の返り値を出力する)としている。printfn は,フォーマット文字列を使用して,引数を埋め込んだ文字列と改行を出力する,C言語タイプのプログラミング言語ではおなじみの関数と同じ働きをする関数である。

コードを走らせる

メニューで表示されているRun の中の Start Without Debugging を選ぶと,プログラムが開始される。デバッグ機能は無効で,すぐに結果が表示されるはずだ。

Visual Studio for Mac が表示したコンソールウィンドウ内に,以下のように表示されただろうか:

12 squared is 144!

F# インタラクティブウィンドウを使う

F#インタラクティブウィンドウとは,コードを入力するとその場で結果が得られるコンソールウィンドウのことである。これを使うには,先程の square 関数の定義記述部分を選択し,メニューの Edit の中の Send selection to F# Interactive を選ぶ。これにより,選択したプログラムコードが F# インタラクティブウィンドウに送られる。別の方法としては,コード選択の後,右クリックで出てくる Send selection to F# Interactive を選ぶという方法もある。このように表示されるはずだ:

>
val square : x:int -> int
>

この表示は,先程見た square 関数の型シグネチャと同じ内容である。square 関数が F# インタラクティブプロセスの中であらためて定義されたので,以下のように別の値を引数として呼び出すことが可能となった:

> square 12;;
val it : int = 144
>square 13;;
val it : int = 169

上記の例では,関数が呼び出され,その結果が it に束縛され,it の型と内容が表示されている。各行を ;; で締めくくっているが,これは,F# インタラクティブ環境に対して関数呼び出しがここで終了していることを知らせている。F# インタラクティブ環境で新しい関数を定義することもできる:

> let isOdd x = x % 2 <> 0;;
val isOdd : x:int -> bool
> isOdd 12;;
val it : bool = false

上記の例では,新しい関数の isOdd を定義している。 int 型の引数を一つとり,奇数かどうかを判定する関数である。さまざまな引数で呼び出してみよう。関数の中で関数を呼び出すことも可能である:

> isOdd (square 15);;
val it : bool = true

パイプ演算子( pipe-forward operator )を使って,値を関数に流し込むこともできる:

> 15 |> square |> isOdd;;
val it : bool = true

パイプ演算子 ( The pipe-forward operator ) については後述する。インタラクティブ環境について,詳しくは Interactive Programming with F# を参照のこと。

次は…

F#言語の主要機能については,Tour of F# や F# Guide を参照のこと。

OmniFocus 3 for iOS – OmniFocus 2 for Macとのデータ互換性

OmniFocus 3 for iOS のデータがOmniFocus 2 for Mac のデータとして使えるかが公式サイトに出ていたので,自分のために要約。結論としては使える。但し,いくつか注意点あり。元になったOmni社のページ「Using OmniFocus 3 for iOS with OmniFocus 2 for Mac」はこちら。現地時間2018年6月7日版に基づく。 “OmniFocus 3 for iOS – OmniFocus 2 for Macとのデータ互換性” の続きを読む

Threepenny-gui とは

Haskell で Rover Mini の ECU データを拾うプロジェクト,ぼちぼち進めています。

開発は MacBook Air 11” でやっていますが,実際の稼働ではラズパイなどワンボードの小型PCでやろうかと。Haskell はあちことのプラットフォームで動くのでいいのですが,問題はGUI。

Real World Haskell などは汎用GUIライブラリの呼び出し例なども掲載されていますが,macOS で他のプラットフォームと共通のデザインだとものすごい違和感を感じます。また,GUI の世界では最近,Functional Reactive Programming という新しい考え方に基づく実装例も増えてきています。そのものずばりの名前の本(Functional Reactive Programming , Manning Publications )も2016年に出版されたので,計算機科学分野の英語の復習の意味も含めて電子ブックを買い求めて読み進めています(ちなみに最近,書店店頭で翻訳本を見かけましたが,意味が読み取りにくい翻訳となっている箇所が多数あったため,購入は見送りました)。

そこで今回のブログ記事では,Haskell の GUI 環境の中でも FRP が使え,ラズパイ でも macOS でも使えそうな Threepenny-gui ライブラリについて調べてみることにしました。

以下はHaskell wiki Threepenny-gui より。2018年1月17日15:00 (JST) 閲覧した際の記述内容に基づいたもの。

1. Threepenny-gui とは

Threepenny-gui とはウェブブラウザーをディスプレイとして見立てた GUI (Graphic Interface Library; グラフィックユーザーインターフェース) のフレームワークである。

以下の機能を持つ:

  • 容易な設置 いまどきは誰でもブラウザをインストールしている。従い、threepenny-gui ライブラリを hackage からインストールするだけでよい。このライブラリは多数のプラットフォームで動作する。
  • HTML + JavaScript ユーザインタフェースを作成する際、HTMLの機能をすべて使用することができる。これは素晴らしいことではあるが、うっかりするとはまり込んでしまうことにもなりかねない。それゆえ、このライブラリには、CSSを使用しなくてもユーザインタフェースを素早く構築できるよう、レイアウトコンビネータが含まれている。またFFI(Foregin function interface; 他言語接続機能)を利用してブラウザの中でJavaScriptを走らせることも可能である。
  • FRR ( Functional Reactive Programming ) により、ユーザーとのやりとりのプログラミングでイベント駆動式のスタイルを伝統的な手続き型言語で構築するときに陥りがちなスパゲッティコードを避けることができる。Threepenny は FRP ライブラリを持っているが、それを使うか否かは自由である。便利と思えばFRPを利用してもよいし、袋小路にはまり込んだと思ったら FRP を使わなくてもよい。

2. Threepenny-gui ができないこと

  • ウェブのフロントエンドではない。サーバはローカルホストで稼働することを想定している。(ネットを経由する)ウェブアプリとして使用するには遅延が問題となるだろう。つまり、ローカルネットワークの多数のユーザーを想定した場面には向いているということ。サンプルコードの Chat.hs example を参照。
  • JavaScript や HTML のライブラリではない。Threepenny-gui は Haskell の API を備える GUI フレームワークであり、ドキュメント・オブジェクトモデルについて様々なことを抽象化している。Threepenny-gui を使うにあたっては、 HTML については多少の知識が必要だが、JavaScript の知識は必要ではない。もっとも、外部クライアントライブラリを活用とする場合はその限りではないが。

ウェブアプリを作ろうとしているなら、他のプロジェクト(たとえばFay, GHCJS, Haste など)を参照のこと。Threepenny の API はこれらのプロジェクトにいくらか影響を与えている、もしくは将来与えることになるかもしれないが、現時点ではそこ(ウェブアプリ開発向きの機能)に焦点はあたっていない。

3.開発経緯

現在、活発に開発が行われいる状況であり、主要なAPIについても将来の版では改訂されているかもしれない。このプロジェクトの目標はGUI プログラミングをできるだけ簡素にすることにある。そのためにやや実験的に様々な挑戦を行っている。

  • 2017.04.29 threepenny-gui-0.8.0.0 公開
  • 2016.09.16 threepenny-gui-0.7.0.0 公開
  • 2015.05.15 threepenny-gui-0.6.0.2 公開
  • 2015.05.13 threepenny-gui 0.6.0.1 公開
  • 2014.10.04 threepenny-gui 0.5.0.0 公開
  • 2013.11.21 threepenny-gui 0.4.0.0 公開
  • 2013.09.07 threepenny-gui 0.3.0.0 公開

4. 応用例

Threepenny を使って書かれたアプリケーションの例

5. 現況と参考資料

Hackage からのダウンロード threepenny-gui

参考資料

フィードバック先および連絡先

github 上のソースコード

Haskellメモ というか,High Sierra と FTDI USB Serial メモ

以前からぼちぼち開発しているRoverMiniコンピュータデータ取扱用のプログラム,ので本日はその原因究明と対策実施。

現象

  • macOS X を High Sierra にしたら,FTDIのUSBシリアル変換機がマック上ではttyデバイスとして認識されなくなった。
  • 同じハードで仮想マシン上のWindows10では同変換器を検出し,正常にECUと通信できるので,マック上のドライバの問題と想定。
  • メーカー(FTDI社)の最新ドライバなどをインストールしてみたが,状況は変わらなかった。
  • High Sierra ではセキュリティ強化のため,場合によっては「システム環境設定」のセキュリティとプライバシー設定で,明示的に権限許可を与えないと動作しない機能拡張があるが,現時点では許可催促の表示は出ていない(ただし,当該催促は最初にその機能拡張が動作しようとしてから一定の時間以内にのみ表示され,その後は消えてしまうとのことなので,OSアップデート後にケーブルを初めて挿入した際,これを見逃した可能性はある)。

原因探索

ネットで検索した所,以下のことがわかり,ドライバが複数あって,衝突して不具合となっている可能性があるものと思われた。

  • Appleは,しばらく前(少なくとも Marverics )から,自社のFTDIチップ用ドライバを mac OS に含めて提供している。
  • 幾つかのサイトでは,FTDI社のドライバとApple社のドライバの切り替えを行って問題が解決したことを報告している。(例1例2例3例4
  • 両ドライバとも,kext形式で提供されている。
  • kextとは,加除可能なOS機能追加モジュールであり,sudo kextstatで現在使われているモジュールの確認ができる他,sudo kextload xx.kext でモジュールを追加することができる。
  • 当該ハードには,OSバージョンアップ前からFTDI社のドライバが入れてあり,機能していたが,こうした場合,High Sierraのインストールでは,(クリーンインストールであっても?)サードパーティー提供のドライバが新たな権限許可を与えずとも動作するようになっている模様。

対策

ドライバを一つにする。Apple社提供のものでまずは実験してみて,その上で,FTDI社のものを実験してみるかを判断することにした。実際の作業としては,以下の通り。

  • 存在しているドライバの確認。→/System/Library/Extentions にAppleUSBFTDI.kext 2017/08/25 14:20 6.0.0 がある。また,Library/Extentions に FTDI社のドライバ D2xxHelper.kext 2015/11/09 2.0.0 があった。
  • kextstat | grep FTDI で動作している機能拡張を確認。今回の場合はなかった(両方共読み込み失敗の様子)。
  • FTDI社のドライバを削除の上,マックを再起動。
  • 手動でAppleのドライバを読み込み(cd /System/Library/Extentions  -> sudo kextload AppleUSBFTDI.kext)
  • kextstat で機能拡張が読み込まれているかを確認。この時点では読み込まれていない。
  • ケーブルを接続。kextstatで状況確認→ドライバが読み込まれている。
  • /dev/ を確認。無事,認識され,/dev/tty.usbserial-DJ0… として表示された。

まとめ

  • 今回のトラブルの原因は複数の機能拡張(ドライバ)を設置したことによる競合。
  • 純正とメーカー製の二種類のドライバで機能・性能が違いそうなので,今後,機能・性能で不審な点があった場合,ドライバを変えてみるという策をとってみる必要がある。

以上

 

Haskellメモ Haddock

この説明は,Haskellの公式サイトの記述を魚野が自分のメモとして部分的に日本語化したもの。
詳細は下記サイト参照。
http://haskell-haddock.readthedocs.io/en/latest/markup.html

1 Haddockとは

Haddockとは,プログラミング言語,Haskellのソースファイルにコメントを記述することで,
自動的に参考用の文書を作成するシステムのこと。

2 Haddockの記法

2-1 トップレベル宣言

・トップレベル(関数の型署名や方宣言,クラス宣言等)での記述。
・「--|」という句で書き出すと,それ以降の部分はその直後の宣言に関する説明となる。

-- | The 'square' function square an integer
square :: Int -> Int
square x = x * x

・トップレベルとは
トップレベルの関数の型署名
型署名のないトップレベルの関数の定義
data 宣言
newtype 宣言
type 宣言
class 宣言
data family または type family 宣言
data instance またはtype instance 宣言
・別の宣言が続いた時は,後の宣言はHaddockに無視される。
・宣言の後にコメントを書くことも可能。

square :: Int -> Int
-- ^ The 'square' function square an integer
square x = x * x

2-2 宣言の一部分へのコメント

・クラスメソッド トップレベル宣言に同じ(「-- |」 や「--^」を使う)。
・コンストラクタ,レコードフィールド 同上

2-3 関数の引数

・「--^」を使う。

f :: Int -- ^ The 'Int' argument
-> Float -- ^ the 'Float' argument
-> IO() -- ^ the return value

2-4 モジュールの説明

・モジュールの説明は記述が多岐にわたることが多い。

{-|
Module : W
Description : Short description
Copyright : (c) Some Guy, 2013
Someone Else, 2014
License : GPL-3
Maintainer : sample@email.com
Stability : experimental
Portability : POSIX

Here is a longer description of this module, containing some
commentary with @some markup@.
-}

・各フィールド全てを記述する必要はない。重要度の順で記述すること。
・各フィールドの中身が二行以上になる時は,フィールドのラベル終了位置よりも右方から記述する。
・但し,冒頭に「--」を記述した際は例外(詳細は冒頭のURL参照)

2−5 モジュールの説明要素

・Module モジュール名
・Description モジュールの概説。
・Copyright, License, Maintainer, Stability できるだけ明示すること
・Portability OSの制約や必要なGHC拡張が記述されることが多い。

3 ドキュメントの構造

・各モジュールが輸出(エクスポート)している要素のみ説明文作成の対象とされる。
・輸入(インポート)されたモジュールで輸出されている場合も説明文作成の対象となる。
・3つの構造がある:セクション頭書,名前付記述,モジュール全体の再輸出

3-1 セクション頭書

・Class, Typeなどは同位のセクション,Type, A data type などはセクションの下位化
・「-- *」,「-- **」などで書き始める。*数はセクションの下位化

3-2 名前付記述

・名前付記述 二個目の「-- $XXX」以降の記述は一個めの「-- $XXX」の部分に置かれる。
XXXは名前)

3-3 ハイパーリンクと要素再輸出

・Haddockは説明文書作成の際,クラス名などを全てハイパーリンクつきにする。

サイトにssl証明導入

ブログ程度の運用しかしていない小さなサイトに必要性があるかどうかはわかりませんが,世の中の情報セキュリティ対策強化の動きに合わせ,一応,SSL証明書を入手し,設置することにしました。http://www.kuono.net だけでなく,https://www.kuono.net でもアクセスできるようになります(現在手続き中)。

導入したのは,ドメインの証明,つまり,このドメインがなりすましサイトにあるわけではないよという内容の証明なので,kuono.net がどこの会社・組織の所有なのかといったようなことは証明されているわけではありません。こういう証明書の発行手数料は,結構値段の張るものです。行政など公的機関がやってくれたらいいのにと思わないわけでもないですが,現在はセコムだとかシマンテックだとかの,大手民間事業者が発行してます。利用しているのは一番価格の低いランクのもので,大手IT関係組織の方あたりには証明にもならないよと笑われそうですが,サイトを利用したサービスをやっているわけでもないので,IT業界の流れをおっかけているという意味では,まぁこれでよいかと。

最近は,支援先の公式サイトのメンテナンスや記事追加支援ばかりで自分のサイトの更新を怠ってきましたが,大学での後期の講座も始まったことですし,6次産業化や認定支援機関としての経営改善計画策定支援など,関わっている業務でもいろいろ情報がたまってきていますので,ぼちぼち記事を追加していきます。

工業経営論第13回

2017年度前期の工業経営論第13回,テーマは標題は生産システムと経営。テキストから離れての講義であり,お膝元,愛知県内の事業者,トヨタに関連する用語が次々と紹介される。愛知県内の工業系の学生が興味をもちやすいテーマでもある。

質問一覧は以下の添付資料の通り。特に7つのムダについて興味を持つ学生が多かったようで,もっとも質問者数が多かった。

20170712工業経営論質問一覧

Haskellメモ inkey$を実現する

難しいことを簡単にし,簡単なことを難しくする,などといわれる純粋関数型言語 Haskell。かつてBasic 言語でプログラミングをしていた際によくつかったinkey$関数の実現方法を調べてみた。

inkey$関数とは実行されたときに押されている一文字からなる文字列を返す関数。キーが押されていないときは””が返ってきたはず(30年以上前の記憶なのでうろ覚え)。

以下のコード〜raspberry pi で動けばいいので,とりあえずはこんなコードで〜を macOS で動作確認したところ,おおむね期待通りに動作した。Windows でどうなるかは不明。

import Data.ByteString as BS
import System.IO

main :: IO ()
main = do
 hSetBuffering stdin NoBuffering -- set non buffering mode 
 keyscaned <- BS.hGetNonBlocking stdin 1 -- ::IO ByteString
 if keyscaned == BS.empty
 then main
 else do
 print keyscaned
 main

Haskell メモ MyECU

Haskell の習作として Rover Mini の ECU (MEMS)モニタソフトを作りかけている。以下はそのために試行錯誤した際のメモ。順次追記予定。

  1. 16進数表記の文字コードを入力し,文字を得る。
    
     do
       charcode <- readLn :: IO Int
       let command = chr charcode
     

    ECUコマンド発行用。ECUコマンドは基本的に1バイト文字。符号なし1バイト整数を意味する Word8 をこの時点から使おうかと思ったが,chr 関数にWord8を引数とさせる方法を調べるのが面倒だった(多分,こちらの記事が役に立つ。あとで調べる。)ので,とりあえず Int で入力させることを決め打ちにしてこのようなコードに。コンパイラオプション({-# LANGUAGE OverloadedStrings #-}ghc -XOverloadedStrings )を活用する方法を使わなかったのは,単に使うオプション類をできるだけ少なくしたいというコーディングスタイルの趣味の問題。

  2. macOS 機または Raspberry Pi での動作を前提とし,USBシリアル変換ケーブル経由のデータのやりとりをデバイスファイル経由で行う。
    
    result 

    ByteString 内の hPut や hPutNoBuffring では,文字を書き込んでも制御が戻ってこない。下層の Unix システムコールを Haskell で使う Posix.IO の wirteFd あたりを使う必要があるか。Haskell の問題というよりは Unix の使い方の知識の問題。
    【2017.05.30 追記】結局,serialPortモジュールを使うことで解決。初期化やデータのやりとりができるようになった。protocol.c では初期化コマンド送出の途中に ping を入れているので,この仕組も取り入れた。

  3. コンソールで入力した16進の文字コードをECU側に発行し,その反応を,時刻付きでコンソールに表示する。
  4. コンソールに表示した時刻と反応のセットを,第二引数で指定したファイルに書き込む。
  5. シリアル通信が途切れたときのための例外処理の追加。