Implementing PSHostRawUserInterface in F# - f#

I am trying to implement the sample here with F# and cannot figure out how to correctly override the two overloads "SetBufferContents" in PSHostRawUserInterface:
#r "System.Management.Automation"
open System
open System.Management.Automation.Host
type MyRawUserInterface() =
inherit PSHostRawUserInterface()
override this.BackgroundColor with get() = Console.BackgroundColor and set v = Console.BackgroundColor <- v
override this.BufferSize with get() = Size(Console.BufferWidth, Console.BufferHeight) and set v = Console.SetBufferSize(v.Width, v.Height)
override this.CursorPosition with get() = raise (NotImplementedException()) and set _ = raise (NotImplementedException())
override this.CursorSize with get() = Console.CursorSize and set v = Console.CursorSize <- v
override this.ForegroundColor with get() = Console.ForegroundColor and set v = Console.ForegroundColor <- v
override this.KeyAvailable with get() = Console.KeyAvailable
override this.MaxPhysicalWindowSize with get() = Size(Console.LargestWindowWidth, Console.LargestWindowHeight)
override this.MaxWindowSize with get() = Size(Console.LargestWindowWidth, Console.LargestWindowHeight)
override this.WindowPosition with get() = Coordinates(Console.WindowLeft, Console.WindowTop) and set v = Console.SetWindowPosition(v.X, v.Y)
override this.WindowSize with get() = Size(Console.WindowWidth, Console.WindowHeight) and set v = Console.SetWindowSize(v.Width, v.Height)
override this.WindowTitle with get() = Console.Title and set v = Console.Title <- v
override this.FlushInputBuffer() = ()
override this.GetBufferContents(_) = raise (NotImplementedException())
override this.ReadKey(_) = raise (NotImplementedException())
override this.ScrollBufferContents(_, _, _, _) = raise (NotImplementedException())
override this.SetBufferContents(origin:Coordinates, contents:BufferCell[,]) = raise (NotImplementedException())
override this.SetBufferContents(rectangle:Rectangle, fill:BufferCell) = raise (NotImplementedException())

You need to specify a return type for the function as raise doesn't have a proper return type (it throws an exception).
This is what it should look like
override this.SetBufferContents(origin:Coordinates, contents:BufferCell[,]) : unit = raise (NotImplementedException())

Related

elegant way to call async functions in a match statement, in F#

This cannot work:
let a () =
async {
return 0
}
let b x =
async {
return
match x with
| true ->
let! y = a() <- you can't compile this
y
| false ->
0
}
I understand I could do this:
let b x =
async {
match x with
| true ->
return! a()
| false ->
return 0
}
but there are cases where I need a:
let! y = a()
to do more operations with the result.
Is there an elegant way to achieve this?
Can't you combine the two?
let b x =
async {
match x with
| true ->
let! y = a()
return y
| false ->
return 0
}
You can move the async expression inside each case:
let b x =
match x with
| true -> async {
let! y = a ()
...
return y
}
| false -> async { return 0 }
I don't know if you think this is more elegant, but more functions usually makes it look a bit nicer, here's an example:
module Async =
let create v = async { return v }
let bind f a = async.Bind (a, f)
let map f a =
bind (f >> create) a
let a () = Async.create 0
let addOne y =
y + 1
let b x =
match x with
| true -> a () |> Async.map addOne
| false -> Async.create 0
// Additional piping to map or bind if you wish, e.g:
// |> Async.bind ...
You can do the return inside the match.
let a () = async {
return 0
}
let b x = async {
match x with
| true -> return! a()
| false -> return 0
}
Otherwise you can do this:
module Async =
let create x = async { return x }
let a () = async {
return 10
}
let b x = async {
let! x1 =
match x with
| true -> a()
| false -> async { return 0 }
let! x2 =
if x then a() else Async.create 0
// Do whatever with x1 or x2
return x2
}
Create a function for code that occur often:
let whatever b a x =
if x then a() else Async.create x
let! y = whatever b a 0

Cannot convert return expression of type '[()]' to return type

I am using the map to update all array values. But it's returning an empty array.
var filterProductList = [CategoryProduct]()
let finalList = filterProductList.map{ p in
if let pf = test.rankings[0].products.first(where: {$0.id == p.id}) {
p.rankCount = pf.viewCount
}
}
return finalList // Showing error here cannot convert return expression of type '[()]' to return type '[CategoryProduct]'
You have to explicitly return p and to specify the return type
let finalList = filterProductList.map{ p -> CategoryProduct in
if let pf = test.rankings[0].products.first(where: {$0.id == p.id}) {
p.rankCount = pf.viewCount
}
return p
}

NSInvalidArgumentException : attempt to insert nil from objects[0]

I have a UIPageViewControllerDataSource initialised as follows:
[<Register ("FlatImagesPageViewDataSource")>]
type FlatImagesPageViewDataSource() as x =
inherit UIPageViewControllerDataSource()
let mutable isinitialised = false
let mutable flatImages : List<UIImage> = List.Empty
let mutable parentView : UIPageViewController = null
let mutable controllers : List<UIViewController> = List.Empty
let viewControllerAtIndex(index : int) =
let mutable result : UIViewController = null
if flatImages.Length = 0 || index >= flatImages.Length then
result <- null
else
let controller = new FlatImagesContentViewController(new IntPtr())
controller.GetImage <- flatImages.[index]
controller.GetPageIndex <- index
if controllers.Length = 0 then
((controller :> UIViewController )::controllers) |> ignore
int(0) |> ignore
else
let listc = List.toArray controllers
listc.[0] <- (controller :> UIViewController)
controllers <- Array.toList listc
int(0) |> ignore
result <- controller
result
member this.GetParentView
with get() = parentView
and set(value) = (
parentView <- value
controllers <- Array.toList parentView.ViewControllers
)
member this.GetFlatImages
with get() = flatImages
and set(value) = (
flatImages <- value
if not isinitialised then
parentView.View.UserInteractionEnabled <- true
if flatImages.Length > 0 then
let initialcontroller = viewControllerAtIndex(0)
let mutable viewControllers : UIViewController list = []
viewControllers <- initialcontroller::viewControllers
parentView.SetViewControllers(viewControllers |> List.toArray,UIPageViewControllerNavigationDirection.Forward,true,null)
controllers <- viewControllers
isinitialised <- true
else
((controllers.[0]) :?> FlatImagesContentViewController).GetImage <- flatImages.[((parentView.ViewControllers.[0]) :?> FlatImagesContentViewController).GetPageIndex]
)
override x.GetNextViewController(pageViewController : UIPageViewController, contentController : UIViewController) =
let mutable returnController : UIViewController = null
if flatImages.Length > 0 then
let curr_index = (contentController :?> FlatImagesContentViewController).GetPageIndex
Console.WriteLine("Attempting after with index ")
Console.WriteLine(curr_index.ToString())
if curr_index < flatImages.Length - 1 then
returnController <- viewControllerAtIndex(curr_index + 1)
returnController
override x.GetPreviousViewController(pageViewController : UIPageViewController, contentController : UIViewController) =
let mutable returnController : UIViewController = null
if flatImages.Length > 0 then
let curr_index = (contentController :?> FlatImagesContentViewController).GetPageIndex
Console.WriteLine("Attempting before with index ")
Console.WriteLine(curr_index.ToString())
if curr_index > 0 then
returnController <- viewControllerAtIndex(curr_index - 1)
returnController
override x.GetPresentationCount(pageViewController : UIPageViewController) =
Conversions.nint(flatImages.Length)
override x.GetPresentationIndex(pageViewController : UIPageViewController) =
let mutable returnVal = 0
if flatImages.Length > 0 then
returnVal <- (controllers.[0] :?> FlatImagesContentViewController).GetPageIndex
Conversions.nint(returnVal)
This code crashes on the line:
parentView.SetViewControllers(viewControllers |> List.toArray,UIPageViewControllerNavigationDirection.Forward,true,null)
in this code block:
member this.GetFlatImages
with get() = flatImages
and set(value) = (
flatImages <- value
if not isinitialised then
parentView.View.UserInteractionEnabled <- true
if flatImages.Length > 0 then
let initialcontroller = viewControllerAtIndex(0)
let mutable viewControllers : UIViewController list = []
viewControllers <- initialcontroller::viewControllers
parentView.SetViewControllers(viewControllers |> List.toArray,UIPageViewControllerNavigationDirection.Forward,true,null)
controllers <- viewControllers
isinitialised <- true
else
((controllers.[0]) :?> FlatImagesContentViewController).GetImage <- flatImages.[((parentView.ViewControllers.[0]) :?> FlatImagesContentViewController).GetPageIndex]
)
with the following exception:
which I don't understand as I have checked that initialController is definitely not null, therefore I don't understand where this exception is coming from.
I notice when you want to use parentView.SetViewControllers(...) the viewControllers only has one object. How do you construct your UIPageViewController?
If you use UIPageViewControllerSpineLocation.Mid or default UIPageViewControllerSpineLocation(default is Mid), it requires at least two controls when you set its ViewControls.
So you can try to modify initial method like:
new UIPageViewController(UIPageViewControllerTransitionStyle.PageCurl,
UIPageViewControllerNavigationOrientation.Horizontal,
UIPageViewControllerSpineLocation.Min)

How to multiply NSstring by the number?

I can't multiply currentValue variable value.
Code:
#IBAction func PlusMinus()
{
let v = 0
command = nil
let currentValue = v
let v = v*(-1)
displayLabel!.text = m
}
what is wrong ?
You can see screenshot :
http://cl.ly/image/3c2e0V0m021H
You are redefining a constant with the same name 'v'. Also, you're using several instance vars in your code. Copy all relevant code in your question.
#IBAction func PlusMinus()
{
let v = 0
command = nil
let currentValue = v
let v = v*(-1) // you've already defined a constant named 'v'
displayLabel!.text = m
}
let declares a constant. It's like writing 2 = 2 * (-1), makes no sense. Use var for variable values.

Swift calling public class in another file

In Swift programming. I have created a public class called Array3d and is inside Array3d.swift file. My ViewController2.swift create a variable called dog by using the Array3d class and i println(dog). However my console does not show the values of the array of dog but show FYP_Table.Array3D instead.
I have created a 3D Array Called dog and inserted some values into it. Now i want to print it to my debugger output. But does not work.
// Array3d.swift
public class Array3D {
var zs:Int, ys:Int, xs:Int
var matrix: [Float]
init(zs: Int, ys:Int, xs:Int) {
self.zs = zs
self.ys = ys
self.xs = xs
matrix = Array(count:zs*ys*xs, repeatedValue:0)
}
subscript(z:Int, y:Int, x:Int) -> Float {
get {
return matrix[ z * ys * xs + y * xs + x ]
}
set {
matrix[ z * ys * xs + y * xs + x ] = newValue
}
}
//ViewController2.swift
class ViewController2: UITableViewController {
var dog = Array3D(zs: 3, ys: 3, xs: 3)
override func viewDidLoad() {
dog[1,0,0] = 1
dog[0,4,0] = 2
dog[0,0,4] = 3
dog[0,4,4] = 4
for z in 0..<3 {
for y in 0..<3 {
for x in 0..<3 {
println(self.dog)
}
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Your class doesn't have a description, so it's just printing out the default representation.
func description() -> String {
return String(format: "Array3D zs:%d ys:%d xs:%d", self.zs, self.ys, self.zs)
}
The proper way to do this is to implement the Printable protocol (see here), which is simply a read-only property named description.
var description : String {
return String(format: "Array3D zs:%d ys:%d xs:%d", zs, ys, zs)
}

Resources